AngularJS对象字段不从子指令更新

时间:2015-05-12 16:30:37

标签: javascript angularjs angular-directive

我有一个父控制器A,其范围包含一个表示其状态的对象。因此,我可以从state.status的范围访问A以更新其状态。

我有一个子指令B,该指令绑定到A状态对象中的字段。这样我就可以从A更新B的状态。

这是我的控制器A的简化代码:

angular.module("myApp").controller('A', function($scope){

    $scope.state = {
        "status": "All"
    };


    function doSomething() {
        console.log(state.status);
    }

});

对于指令B

angular.module('myApp').directive('B', function () {

    return {
        templateUrl: 'B.html',
        scope: {
            selectedStatus: '=status',
            onChange: '=onChange'
        },
        link: function (scope, element, attrs) {
            scope.setStatus = function(status) {
                scope.selectedStatus = status;
                scope.onChange();
            };
        }
    }

});

在DOM中:

<B status="state.status" on-change="doSomething" />

当我从我的指令setStatus()中调用B时,我希望在调用时间doSomething()之前传播我对该对象所做的更改。但是,console.log()输出具有旧值,而不是我刚刚更新的值。做出改变,但速度不够快。

我已尝试拨打$scope.$apply()但是它已经抱怨它已经在$scope.$apply()通话中了。 :(

处理此问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

你对这是如何运作有点困惑。

当您执行status="state.status"之类的操作并更改指令内的状态时,更改将仅在执行摘要周期后应用,但在您的情况下,您尝试在完成摘要之前输出state.status,因此它不使用同步值。

有几种方法可以解决这个问题:

  1. scope.onChange
  2. 内拨打$timeout
  3. 传递完整对象state而不是state.status
  4. 使用scope.$parent访问您定义state object
  5. 的父作用域

    angular.module("myApp", []).directive('bb', function($timeout) {
      return {
        template: '<div><div ng-click="setStatus1(\'status1\')">1. Selected status: {{selectedStatus}}</div><div ng-click="setStatus2(\'status2\')">2. Selected status: {{selectedStatus}}</div><div ng-click="setStatus3(\'status3\')">3. Selected status: {{selectedStatus}}</div></div>',
        scope: {
          selectedStatus: '=status',
          onChange: '=onChange',
          state: '='
        },
        link: function(scope, element, attrs) {
          scope.setStatus1 = function(status) {
            console.log('setstatus1');
            scope.selectedStatus = status;
            $timeout(function() {
              scope.onChange();
            });
          };
          scope.setStatus2 = function(status) {
            console.log('setstatus2');
            scope.selectedStatus = status;
            scope.state.status = status;
            scope.onChange();
          };
          scope.setStatus3 = function(status) {
            console.log('setstatus3');
            scope.selectedStatus = status;
            scope.$parent.state.status = status;
            scope.onChange();
          };
        }
      }
    
    }).controller('A', function($scope) {
    
      $scope.state = {
        "status": "All"
      };
      $scope.doSomething = doSomething;
    
      function doSomething() {
        console.log('doSomething: ', $scope.state.status);
      }
    
    });
    <script data-require="angular.js@1.4.0-rc.1" data-semver="1.4.0-rc.1" src="https://code.angularjs.org/1.3.8/angular.js"></script>
    <div ng-app="myApp" ng-controller="A">
      <bb status="state.status" state="state" on-change="doSomething"></bb>
      {{state}}
    </div>

答案 1 :(得分:0)

在父指令中而不是传递回调,您可以使用$("#divisionDropDown") .append( $("<li />", { "html": $("<a />", {"href":"#", "html":item.modelName}), // I had to break up the quotes around the items: // "onclick": "modelClick('"+item.modelName+"', '" + item.subdivisionId + "')" "onclick":"modelClick('"+item.modelName+"', '" + item.subdivisionId + "')" // return `element.outerHTML` `String` })[0].outerHTML );

$watch