【问题标题】:Isolated scope directive with two way binding doesn't reflect changes in controller's scope具有双向绑定的隔离范围指令不反映控制器范围的更改
【发布时间】:2014-07-24 23:54:09
【问题描述】:

总结:

当尝试修改已在隔离作用域指令中为双向数据绑定设置的作用域变量(数组)时,对隔离作用域指令中变量的修改不会反映控制器作用域内的更改。

玩具示例:

目前我有一个排序指令,我想在使用 ng-repeat 的表上定义它。 ng-repeat 使用 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

这些更改不是在控制器内部进行的,因此表格不会按预期更改。

这是一个普通的 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="angular.js@*" 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);
        }

      }
    }

  }])

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    问题是您没有在 click 函数中调用 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 ($apply) 以将任何模型更改通过系统传播到“Angular 领域”之外的视图(控制器、服务、Angular 事件处理程序)。

    【讨论】:

      猜你喜欢
      • 2014-04-28
      • 1970-01-01
      • 2017-09-05
      • 1970-01-01
      • 2015-01-04
      • 2016-01-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多