Как правильно использовать изолированное свойство области?

Как правильно использовать изолированное свойство области?

У меня есть директива, которая вызывается из контроллера страницы, с атрибутом item перешли к нему, например <my-directive item="myItem"></my-directive>, содержащий id,

Код ниже не будет работать, как кажется $scope.item не определено в контроллере.. как будто я использую его слишком рано. Как я могу быть уверен, что он действительно установлен, когда я хочу его использовать?

app.directive('myDirective', [function() {
return {
    restrict: 'E',
    templateUrl: 'template.html',
    scope: {
        item: "="
    },
    controller: ['$scope', 'ExtendedItemFactory', function($scope, ExtendedItemFactory) {
        this.extendedInfo = ExtendedItemFactory.get({ id: $scope.item.id });
    }],
    controllerAs: 'MyDirectiveCtrl'
};
}]);

3 ответа

Решение

Вы могли бы использовать $watch внутри вашей директивы, которая будет следить за изменением значения и запускать код, который вы хотите.

Код

app.directive('myDirective', [function() {
    return {
        restrict: 'E',
        templateUrl: 'template.html',
        scope: {
            item: "="
        },
        controller: ['$scope', 'ExtendedItemFactory', function($scope, ExtendedItemFactory) {
            this.extendedInfo = ExtendedItemFactory.get({
                id: $scope.item.id
            });
            $scope.$watch('item', function(newVal, oldVal) {
                if (newVal && newVal != oldVal)
                    this.extendedInfo = ExtendedItemFactory.get({
                        id: $scope.item.id
                    });
            }, true).bind(this);
        }],
        controllerAs: 'MyDirectiveCtrl'
    };
}]);

Вместо инициализации extendedInfo когда директива загружается, вы можете создать функцию получения, которая извлекает ее по требованию.

this.getExtendedInfo = function(){
    return ExtendedItemFactory.get({ id: $scope.item.id });
}

Кроме того, вы не можете загрузить свою директиву до item готов

<div ng-if="ctrl.item">
    <my-directive item="ctrl.item"></my-directive>
</div>

Вы используете controllerAs, поэтому вам не нужно вводить $scope в этом случае.

Я бы изменил определение вашей директивы на следующее, отметив использование bindToController, который обеспечит заполнение и доступность значений изолированной области на вашем контроллере:

app.directive('myDirective', [function() {
    return {
        restrict: 'E',
        templateUrl: 'template.html',
        scope: {
            item: "="
        },
        controller: ['ExtendedItemFactory', function(ExtendedItemFactory) {
            this.extendedInfo = ExtendedItemFactory.get({ id: this.item.id });
        }],
        controllerAs: 'MyDirectiveCtrl',
        bindToController: true
    };
}]);
Другие вопросы по тегам