范围。$ watch(attrs。不使用自定义指令

时间:2015-10-21 02:34:23

标签: angularjs

我正在使用范围。$ watch查找基于属性的指令的更改。这些更改由视图中输入元素的ng模型绑定启动。正在使用范围。$ watch在指令中监视视图上的指令属性。然而,改变事件似乎从未在指令中触发。是什么导致我的代码破坏?

下面代码中突出显示的部分,我登录到控制台(在指令代码中,带有星星),从不会触发。通过输入上的ng-model对控制器范围的更改不会传播到指令。

如果我将属性值更改为静态字符串,而不是通过ng-model绑定它,则可以正常工作。

此代码取自AngularJS文档here中的工作示例。我无法发现差异'因为文档中的代码与我的代码非常相似。

angular.module('myApp.advancedDirectives', [
  'myApp.advancedDirectives.advancedDirectives-directive'
])


.value('data', { name: 'John', surname: 'Smith' })


angular.module('myApp.advancedDirectives.advancedDirectives-directive', [])

.directive('advancedDirectives', ['$interval', 'dateFilter', 'data', function ($interval, dateFilter, data) {
    console.log(data.length);

    function link(scope, element, attrs) {
        var format,
            timeoutId;

        scope.$watch(attrs.advancedDirectives, function (theFormat) {
            format = theFormat;
            **console.log(theFormat);
            updateTime();**
        });

    element.on('$destroy', function () {
        $interval.cancel(timeoutId);
    });


    // start the UI update process; save the timeoutId for canceling
    timeoutId = $interval(function () {
        updateTime(); // update DOM
    }, 1000);

    function updateTime() {
        scope.directiveScope2 = dateFilter(new Date(), format);
    }
}

    var theScope = {
    directiveScope1: '=info'
}

return {
    templateUrl: 'components/advancedDirectives/advancedDirectivesTemplate.html',
    scope: theScope,
    link: link
}
}]);

<div ng-controller="viewAdvancedDirectivesCtrl">
    <div>
        <div><input ng-model="theViewFormat"/></div>
        <div>Data from the directive scope: <span advanced-directives="theViewFormat" info='data'></span></div>
    </div>
</div>





<span style='background:yellow'>Advanced Directive. Here is some data: {{directiveScope1.name}} {{directiveScope1.surname}}, alive at {{directiveScope2}}</span>

2 个答案:

答案 0 :(得分:0)

当您在指令中使用隔离范围时,theViewFormat值在指令上下文中不可用。

您需要在放置$parent.+ attrs.advancedDirectives

时使用$watch

更优选的方式是将advancedDirectives via属性传递给隔离范围,就像传递info数据一样

var theScope = {
    directiveScope1: '=info',
    advanced: '=advancedDirectives'
}

然后,只需将您的手表放在'advanced'字符串上。

scope.$watch('advanced', function (theFormat) {
     format = theFormat;
     console.log(theFormat);
     updateTime();**
});

答案 1 :(得分:0)

以下是我的回答:

下面,请参阅视图代码。 注意:我在{{theViewFormat}}

中使用了大括号
<div ng-controller="viewAdvancedDirectivesCtrl">
    <div>
        <div>Data from the directive scope: <span advanced-directives="{{theViewFormat}}" info='data'></span></div>
    </div>
</div>

链接代码如下所示。 注意:使用$ observe(由@Anik推荐) 注意:我正在观察attrs而不是指令范围对象,因此避免了对updateTime的递归调用,现在我正在观察属性更改,而不是符合我要求的范围更改。

function link(scope, element, attrs) {
        var format,
            timeoutId;


        attrs.$observe('advancedDirectives', function (theFormat) {
            format = theFormat;
            console.log('format changed: ' + format);
            updateTime();
        });

    element.on('$destroy', function () {
        $interval.cancel(timeoutId);
    });


    // start the UI update process; save the timeoutId for canceling
    timeoutId = $interval(function () {
        updateTime(); // update DOM
    }, 1000);

    function updateTime() {
        scope.directiveScope2 = dateFilter(new Date(), format);
        console.log('updateTime: ' + format + dateFilter(new Date(), format));
    }
}

更新指令范围的 updateTime()代码如下:

function updateTime() {
        scope.directiveScope2 = dateFilter(new Date(), format);
        console.log('updateTime: ' + format + dateFilter(new Date(), format));
    }

感谢@Pankaj和@Anik为我提供了很长的路要走。