angularjs - AngularJs 中的独立作用域何时绑定(bind)到父作用域?

标签 angularjs angularjs-directive angularjs-scope

在编译/链接过程的哪个阶段,来自指令隔离范围的变量绑定(bind)到父( Controller )范围?我有一个应用程序,我想在加载 View 后立即自动调用指令 api。

我了解范围绑定(bind) happens in the directive linking phase ,以便在链接后,在隔离作用域上公开的变量应该在父作用域上可用。

但是,我发现情况并非如此,如下面的代码所示( plunker here )。

//plunker code
var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';

  $scope.buttonClick = function() {
    console.log("In buttonClick function, call is: " + this.call);
    this.call();
  }

  $scope.$on("LinkComplete", function(event) {
    console.log("In LinkComplete, call is: " + event.currentScope.call);
    //event.currentScope.call();
  });

  console.log("In Constructor, call is: " + this.call);
})
.directive('myDirective', function(){
  return {
    scope: {
      myMethod: '='
    },
    controller: function ($scope) {
      $scope.myMethod = function() {
        alert("method called");
      };
    },
    link: function postLink(scope) 
    {
        scope.$emit("LinkComplete");
    }
  };
});

<body ng-controller="MainCtrl">
  <p>Hello {{name}}!</p>
  <div my-directive my-method="call"></div>
  <button ng-click="buttonClick()">Call</button>
</body>

请注意,代码在 View 初始化期间两次尝试访问链接变量(指向指令 Controller 上的方法),并且在这两种情况下,该变量都是未定义的。我不希望该变量在主 Controller 构造函数期间可用,但我希望它在链接后事件处理程序期间可用。加载 View 后,绑定(bind)变量就可用(单击“调用”按钮即可见证)。

如何从 Controller 访问绑定(bind)变量,而不需要用户单击按钮等?

最佳答案

这是一个很好的问题,当你看到像“x is y in z stage”这样的词时,你需要小心准确性,总是深入源代码来证明它。

你的骗子正在使用 v1.2.27,检查这一行: https://github.com/angular/angular.js/blob/v1.2.27/src/ng/compile.js#L1492

isolateScope.$watch(function parentValueWatch() {
  var parentValue = parentGet(scope);
  if (!compare(parentValue, isolateScope[scopeName])) {
    // we are out of sync and need to copy
    if (!compare(parentValue, lastValue)) {
      // parent changed and it has precedence
      isolateScope[scopeName] = parentValue;
    } else {
      // if the parent can be assigned then do so
      parentSet(scope, parentValue = isolateScope[scopeName]);
    }
  }
  return lastValue = parentValue;
}, null, parentGet.literal);

这将在下一个 $digest 周期中进行评估,然后 parentScope.call 将被分配。同时,其正下方同步执行postLink函数: https://github.com/angular/angular.js/blob/v1.2.27/src/ng/compile.js#L1575

// POSTLINKING
for (i = postLinkFns.length - 1; i >= 0; i--) {
  try {
    linkFn = postLinkFns[i];
    linkFn(linkFn.isolateScope ? isolateScope : scope, $element, attrs,
      linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn);
  } catch (e) {
    $exceptionHandler(e, startingTag($element));
  }
}

执行 postLink 后, Controller 收到事件,但 parentScope.call 尚未通过 $digest 初始化。

因此,如果您添加一个 setTimeout 来检查,它看起来就像您想要的:

$scope.$on("LinkComplete", function(event) {
    setTimeout(function () {
        console.log("In LinkComplete, call is: " + event.currentScope.call);
        //event.currentScope.call();
    });
});

关于angularjs - AngularJs 中的独立作用域何时绑定(bind)到父作用域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27840205/

相关文章:

javascript - Angularjs 使用 ng-show 条件来比较两种不同的日期格式

javascript - 如何将 ng-model 的引用作为函数的参数传递?

angularjs - 在 Angular 中与嵌套指令共享隔离范围

javascript - 未选中 ng-repeat 列表中的复选框时禁用按钮

javascript - AngularJS:在 ng-model 上搜索多个值

php - 使用我的 PHP 服务将 AngularJS 连接到 mysql?

javascript - 从指令调用 Controller 函数(使用从指令传递的参数)

javascript - AngularStrap 工具提示禁用了我的自定义指令

javascript - Angular 访问范围属性

javascript - ng-click 指令不调用 Controller 函数