2014-07-24 80 views
1

总结:隔离范围指令不反映在控制器的范围的变化

当试图修改已设置为双向数据作用域的分离物中结合一个范围的变量(一个阵列)指令中,对隔离范围指令中变量的修改不反映控制器范围内的更改。

玩具例子:

目前,我有,我想定义上正在使用NG重复的表的排序指令。 NG-重复使用相同的数据在ATableController控制器范围来创建该表:

$scope.tableData = [{'col1' : 1,'col2' : 'fff'}, 
          {'col1' : 2,'col2' : 'aaa'}, 
          {'col1' : 3,'col2' : 'bbb'}, 
          {'col1' : 4,'col2' : 'ccc'}]; 

我想排序指令从其分离的范围内的操作相同的数据。

在指令设置为以下

... scope : 
        { 
        tableSortData  : '=', 
        tableSortRowAccessor : '=', 
        tableSortPrimer  : '=' 
        }, 
... 

在指数简称为以下

... 
<body ng-controller="ATableController"> 
     <table table-sort table-sort-data="tableData"> 
... 

中的链接功能的点击处理程序被分配到表头。点击这个处理程序会触发最终运行这行代码的sort函数。

scope.tableSortData = []; //which would be a sorting line in the real code

这些变化是NOT从控制器内,因此如预期的表不改变制造。

这是一个香草JS问题,(错误的引用正在制作等等)或者是它与我的角度指令。无论哪种方式,我做错了什么,以及如何解决这个问题?

验证码:

plunkr

http://plnkr.co/edit/5yxRj6?p=info

的index.html

<head> 
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
    <script data-require="[email protected]*" data-semver="1.2.0" src="http://code.angularjs.org/1.2.0/angular.js"></script> 
    <link rel="stylesheet" href="style.css" /> 
    <script src="script.js"></script> 
    </head> 

    <body ng-controller="ATableController"> 
    <table table-sort table-sort-data="tableData"> 
    <thead> 
     <tr> 
      <th>Column1</th> 
      <th>Column2</th> 
     </tr> 

    </thead> 
    <tbody> 
     <tr ng-repeat="row in tableData" > 
      <td>{{row.col1}}</td> 
      <td>{{row.col2}}</td> 
     </tr> 
    </tbody> 
    </table> 
    </body> 

</html> 

的script.js

var myApp = angular.module('myApp', []) 

    .controller('ATableController', function($scope) 
    { 
     $scope.tableData = [{'col1' : 1,'col2' : 'fff'}, 
         {'col1' : 2,'col2' : 'aaa'}, 
         {'col1' : 3,'col2' : 'bbb'}, 
         {'col1' : 4,'col2' : 'ccc'}]; 

    }) 

    .directive('tableSort', [function() 
    { 
    return { 
     restrict : 'A', 
     replace : false, 

     scope : 
     { 
     tableSortData  : '=', 
     tableSortRowAccessor : '=', 
     tableSortPrimer  : '=' 
     }, 

     link : function(scope, element) 
     { 
     console.log(scope.tableSortData); 

     // Await click events on header 
     element.find('th').on('click.header', function(event) 
     { 
      var field = $(event.target).attr('field-name'); 
      augmentTableSortData(); 
     }); 

     function augmentTableSortData() 
     { 
      console.log(scope); 
      console.log(scope.tableSortData); 
      scope.tableSortData = []; 
      console.log(scope.tableSortData); 
     } 

     } 
    } 

    }]) 

回答

4

的问题是,你是不是在你的点击功能scope.apply调用:

function augmentTableSortData() 
    { 
     console.log(scope); 
     console.log(scope.tableSortData); 
     scope.tableSortData = []; 
     console.log(scope.tableSortData); 
     scope.$apply(); // <------ this needs to be called because the scope data is being modified in the click function outside of angular's digest cycle. 
    } 

示范:http://plnkr.co/edit/as5Wek?p=preview

Documentation

作用域提供的API(应用$)至通过系统将任何模型更改传播到“Angular领域”(控制器,服务,Angular事件处理程序)之外的视图中。