2015-10-21 201 views
0

我正在使用scope。$ watch来查找基于属性指令的更改,这些更改由ng-model绑定在在视图中的视图。该指令属性被该指令使用范围。$表关注。然而,变化事件似乎从来没有在指令中火。是什么原因造成我的代码来打破?

的部分突出在下面的代码中,我登录到控制台的位置(在指令代码中,星号),决不会触发。通过输入上的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> 

回答

0

由于您正在为您的指令使用隔离范围,因此theViewFormat值在指令上下文中不可用。

要么你需要使用$parent.+ attrs.advancedDirectives同时将$watch

OR

更优选的方法是通过advancedDirectives通过属性来隔离范围像你这样传递info数据

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

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

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

谢谢@Panjak(以及@Anik)你的建议是观察指令范围。但是这给我留下了一个问题,因为当我更新updateTime()中的指令作用域时,它重新启动手表,并且我留下了错误的值。我想观察/观察的是_attribute value_,这样日期时间的格式就可以暴露给用户。 – Banoona

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)); 
    } 
} 

录入()代码,这将更新指令范围如下:

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

感谢@Pankaj和@Anik你为我今后很长的路要走。