【问题标题】:scope.$watch(attrs. is not working with a custom directivescope.$watch(attrs. 不使用自定义指令
【发布时间】:2015-10-21 02:34:22
【问题描述】:

我正在使用 scope.$watch 来查找基于属性的指令的更改。这些更改由视图中输入元素上的 ng-model 绑定启动。视图上的指令 attribute 正在使用指令中的 scope.$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>

【问题讨论】:

    标签: angularjs


    【解决方案1】:

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

    在放置$watch时,您需要使用$parent.+ attrs.advancedDirectives

    更首选的方式是将advancedDirectives 通过属性传递到隔离范围,就像传递info 数据一样

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

    那么你的手表就会在'advanced'字符串上。

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

    【讨论】:

    • 感谢@Panjak(以及@Anik)您的建议是观察指令范围。但这给我留下了一个问题,因为当我在 updateTime() 中更新指令范围时,它会重新触发手表,并且我得到了错误的值。我要观察/观察的是 属性值,以便可以向用户公开日期时间的格式。
    【解决方案2】:

    这是我的答案:

    下面,请看查看代码。 注意:我为 {{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 让我取得了长足的进步。

    【讨论】:

      猜你喜欢
      • 2014-10-17
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-31
      • 1970-01-01
      • 2012-06-23
      • 1970-01-01
      相关资源
      最近更新 更多