更改指令中的控制器范围变量不会反映在控制器功能中

sq1*_*020 3 angularjs angularjs-directive

在我的指令中,我有一个控制器变量,当你按下指令中的按钮时,该页面会增加.但是,scope.alertPage()调用控制器功能的下一行不会反映此更改.请注意,当您单击按钮页面时仍然会被警告为1!

我知道我可以通过在控制器中添加$ scope.$ apply来解决这个问题,但后来我得到的错误是已经发生了摘要.

Plunker

app = angular.module('app', []);

app.controller('myCtrl', function($scope) {

  $scope.page = 1;

  $scope.alertPage = function() {
    alert($scope.page);
  }

})

app.directive('incrementer', function() {
  return {
    scope: {
      page: '=',
      alertPage: '&'
    },
    template: '<button ng-click="incrementPage()">increment page</button>',

    link: function(scope, elem, attrs) {
      scope.incrementPage = function() {
          scope.page += 1;
          scope.alertPage();
      }
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

html模板:

  <body ng-app='app' ng-controller='myCtrl'>
    page is {{page}}

    <incrementer page='page' alert-page='alertPage()'></incrementer>
  </body>
Run Code Online (Sandbox Code Playgroud)

PSL*_*PSL 7

它没有立即显示更新值的原因是因为2路绑定仅在摘要周期期间更新父级(或指令的使用者范围)范围的绑定值.触发ng-click后会发生摘要循环.因此$scope.page在控制器中尚未更新.您可以通过使用a timeout来推断动作在摘要周期结束时运行,从而以多种方式解决这个问题.您也可以通过设置一个将值保存为双向绑定属性的对象来完成此操作.由于双向绑定属性和父作用域共享相同的对象引用,因此您将立即看到更改.

方法1 - 使用超时:

  scope.incrementPage = function() {
     scope.page += 1;
     $timeout(scope.alertPage)
  }  
Run Code Online (Sandbox Code Playgroud)

方法2 - 绑定对象:

 //In your controller
 $scope.page2 = {value:1};

//In your directive 
scope.incrementPage = function() {
     scope.page.value += 1;
     scope.alertPage();
 }  
Run Code Online (Sandbox Code Playgroud)

方法3 - 使用带参数的函数绑定传递值:

//In your controller
$scope.alertPage = function(val) {
  alert(val);
}
Run Code Online (Sandbox Code Playgroud)

<!--In the view-->
<div incrementer page="page" alert-page="alertPage(page)"></div>
Run Code Online (Sandbox Code Playgroud)

//In the directive
scope.incrementPage = function() {
     scope.page += 1;
     scope.alertPage({page:scope.page});
 }  
Run Code Online (Sandbox Code Playgroud)

app = angular.module('app', []);

app.controller('myCtrl', function($scope) {

  $scope.page = 1;
  $scope.page2 = {value:1};
  
  $scope.alertPage = function() {
    alert($scope.page);
  }
  
  $scope.alertPage2 = function() {
    alert($scope.page2.value);
  }

})

app.directive('incrementer', function($timeout) {
  return {
   
    scope: {
      page: '=',
      alertPage: '&',
      page2:"=",
      alertPage2: '&'
    },
    template: '<button ng-click="incrementPage()">increment page</button>',

    link: function(scope, elem, attrs) {
      scope.incrementPage = function() {
          scope.page += 1;
          scope.page2.value += 1;
          $timeout(function(){ scope.alertPage() });
          scope.alertPage2();
      }
    }
  }
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
  <div incrementer page="page" alert-page="alertPage()" page2="page2" alert-page2="alertPage2()"></div>
  </div>
Run Code Online (Sandbox Code Playgroud)