简体   繁体   English

AngularJS控制器功能未触发

[英]AngularJS controller function not firing

I have 3 directives, "parenta", "parentb", and "childb". 我有3个指令,“ parenta”,“ parentb”和“ childb”。 "parenta" and "parentb" are siblings, while "childb" is a direct child of "parentb". “ parenta”和“ parentb”是兄弟姐妹,而“ childb”是“ parentb”的直接子代。

I am trying to call a controller method from "parenta", however it is not working. 我正在尝试从“ parenta”调用控制器方法,但是它不起作用。 For some strange reason, trying to call a method on "childb" controller FROM "parenta" is working instead. 由于某些奇怪的原因,尝试从“ parenta”调用“ childb”控制器上的方法正在工作。 What is happening? 怎么了?

var mod = angular.module("app", []);

mod.directive("parenta", function () {
    return {
        template: "<section><div ng-click='vm.a()'>Rendered by a</div></section>",
        replace: false,
        controllerAs: "vm",
        controller: function () {
            this.a = function () {
                console.log("a called!");
            }
        }
    }
})

mod.directive("parentb", function () {
    return {
        template: "<childb></childb>",
        replace: false
    }
})

mod.directive("childb", function () {
    return {
        template: "<section><div ng-click='vm.b()'>Rendered by b</div></section>",
        replace: false,
        controllerAs: "vm",
        controller: function () {
            this.b = function () {
                console.log("b called!");
            }
        }
    }
})

Html: HTML:

<div ng-app="app">
    <parenta></parenta>
    <parentb></parentb>
</div>

Codepen: http://codepen.io/anon/pen/pJMpVe Codepen: http ://codepen.io/anon/pen/pJMpVe

The issue here is that your directives do not create a child or an isolate scope and use scope: false (which is the default). 这里的问题是您的指令不会创建子范围或隔离范围,而不会使用scope: false (默认设置)。

That means that for a given scope, each directive with its aliased controller, create a scope property called vm - both on the same scope . 这意味着对于给定的作用域,每个带有其别名控制器的指令都在同一个作用域上创建一个名为vm的作用域属性。 And so, childb overwrites the vm property initially created by parenta . 因此, childb覆盖vm最初由创建财产parenta

You can check this quite easily - change one of controllerAs aliases to something else. 您可以很容易地进行检查-将controllerAs别名之一更改为其他名称。

An easy fix - and the right thing to do - is to use either scope: true or scope: {} . 一个简单的解决方法(正确的做法)是使用scope: truescope: {}

I used link function instead of controller. 我用链接功能代替控制器。

Directive controllers are used in AngularJS for inter-directive communication, while link functions are fully contained and specific to the directive instance. 指令控制器在AngularJS中用于指令间通信,而链接功能则完全包含在其中并且特定于指令实例。 By interdirective communication, we mean when one directive on an element wants to communicate with another directive on its parent or on the same element. 间接通信,是指元素上的一个指令要与其父元素或同一元素上的另一个指令进行通信时。 This encompasses sharing state or variables, or even functions. 这包括共享状态或变量,甚至函数。

In the below code I commented the controller function and placed link function 在下面的代码中,我评论了控制器功能并放置了链接功能

 <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> </head> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script> <script type="text/javascript"> var mod = angular.module("app", []); mod.directive("parenta", function () { return { /*template: "<section><div ng-click='vm.a()'>Rendered by a</div></section>",*/ template: "<section><div ng-click='a()'>Rendered by a</div></section>", replace: false, link: function($scope,$element,$attrs) { $scope.a = function() { console.log("a called!"); } } /* controllerAs: "vm", controller: function () { this.a = function () { alert("a called!"); console.log("a called!"); } } */ } }) mod.directive("parentb", function () { return { template: "<childb></childb>", replace: false } }) mod.directive("childb", function () { return { template: "<section><div ng-click='vm.b()'>Rendered by b</div></section>", replace: false, controllerAs: "vm", controller: function () { this.b = function () { console.log("b called!"); } } } }) </script> <body> <div ng-app="app"> <parenta></parenta> <parentb></parentb> </div> </body> </html> 

or if we want to use controller directive then better to use Directive Isolate Scopes along with. 或者,如果我们要使用控制器指令,则最好同时使用指令隔离范围

Unlike a controller, which is paired with a newly created scope when created, a directive is not given a scope of its own by default. 与控制器在创建时会与新创建的作用域配对的控制器不同,默认情况下不会为指令赋予其自身的作用域。 Instead, it simply uses the scope that is available, based on its location in the DOM. 相反,它只是根据其在DOM中的位置来使用可用的范围。

Isolate scope just means giving the directive a scope of its own that does not inherit from the existing scope. 隔离作用域仅意味着为指令赋予其自身的作用域,该作用域不继承现有作用域。

so we use 所以我们用

scope: true in our parenta 范围:适用于我们的父母身分

 mod.directive("parenta", function () { return { template: "<section><div ng-click='vm.a()'>Rendered by a</div></section>", replace: false, scope: true , // Isolate scope controllerAs: "vm", controller: function () { this.a = function () { console.log("a called!"); } } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM