简体   繁体   English

AngularJS从控制器访问指令中的属性

[英]AngularJS accessing an attribute in a directive from a controller

I need to pass an Id defined in the directive to the associated controller such that it can be used in a HTTP Get to retrieve some data. 我需要将指令中定义的ID传递给关联的控制器,以便可以在HTTP Get中使用它来检索一些数据。

The code works correctly in its current state however when trying to bind the Id dynamically, as shown in other questions, the 'undefined' error occurs. 该代码在当前状态下可以正常工作,但是在尝试动态绑定ID时(如其他问题所示),发生“未定义”错误。

The Id needs to be defined with the directive in HTML to meet a requirement. 需要使用HTML中的指令定义ID才能满足要求。 Code follows; 代码如下;

Container.html Container.html

<div ng-controller="IntroSlideController as intro">
   <div intro-slide slide-id="{54BCE6D9-8710-45DD-A6E4-620563364C17}"></div>
</div>

eLearning.js eLearning.js

var app = angular.module('eLearning', ['ngSanitize']);

app.controller('IntroSlideController', ['$http', function ($http, $scope, $attrs) {
    var eLearning = this;
    this.Slide = [];
    var introSlideId = '{54BCE6D9-8710-45DD-A6E4-620563364C17}'; //Id to replace

    $http.get('/api/IntroSlide/getslide/', { params: { id: introSlideId } }).success(function (data) {
        eLearning.Slide = data;
    });
}])
    .directive('introSlide', function () {
        return {
            restrict: 'EA',
            templateUrl: '/Modules/IntroSlide.html',
            controller: 'IntroSlideController',
            link: function (scope, el, attrs, ctrl) {
                 console.log(attrs.slideId); //Id from html present here
            }
        };
    });

Instead of defining a controller div that wraps around a directive, a more appropriate approach is to define a controller within the directive itself. 除了定义环绕指令的控制器div ,更合适的方法是指令本身定义一个控制器。 Also, by defining an isolated scope for your directive, that slide-id will be available for use automatically within directive's controller (since Angular will inject $scope values for you): 另外,通过为指令定义隔离范围,该slide-id将可在指令的控制器内自动使用(因为Angular会为您注入$scope值):

.directive('introSlide', function () {
    // here we define directive as 'A' (attribute only)
    // and 'slideId' in a scope which links to 'slide-id' in HTML
    return {
        restrict: 'A',
        scope: {
            slideId: '@'
        },
        templateUrl: '/Modules/IntroSlide.html',
        controller: function ($http, $scope, $attrs) {
            var eLearning = this;
            this.Slide = [];

            // now $scope.slideId is available for use
            $http.get('/api/IntroSlide/getslide/', { params: { id: $scope.slideId } }).success(function (data) {
                eLearning.Slide = data;
            });
        }
    };
});

Now your HTML is free from wrapping div : 现在,您的HTML无需包装div

<div intro-slide slide-id="{54BCE6D9-8710-45DD-A6E4-620563364C17}"></div>

In your IntroSlide.html , you probably have references that look like intro.* (since your original code use intro as a reference to controller's $scope ). 在您的IntroSlide.html ,您可能具有类似于intro.*引用(因为您的原始代码将intro用作对控制器$scope的引用)。 You will probably need to remove the intro. 您可能需要删除该intro. prefix to get this working. 前缀使此工作。

Require your controller inside your directive, like this: 在指令中要求您的控制器,如下所示:

app.directive( 'directiveOne', function () {
      return {
        controller: 'MyCtrl',
        link: function(scope, el, attr, ctrl){
           ctrl.myMethodToUpdateSomething();//use this to send/get some msg from your controller
        }
      };
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM