范围不得到与编译阶段增加了新的元素相关联 [英] Scope doesn't get associated with new element added in compile phase

查看:90
本文介绍了范围不得到与编译阶段增加了新的元素相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在低于code我试图在编译阶段添加一个按钮,并分配NG,即可从范围的方法。
在链接阶段,经过调试,我发现了compiledEle包含按钮,然后还NG-点击不调用范围的方法。

In below code i am trying to add a button at compile phase, and assigned ng-click to a method from scope. During linking phase, through debugging I found the "compiledEle" contains the button, then also ng-click doesn't call the scope method.

angular.module("app", [])
        .controller("ctrl1", function($scope){
            $scope.myModelObj = {
                name: 'Ratnesh',
                value: 100
            };
        })
        .directive("dirOne",function($compile){
            return {
                restrict: 'E',
                scope: {
                    myModel : "="
                },
                compile: function(ele){
                    ele.append("<button ng-click=\"showAlert()\">click ME</button>")
                    return {
                        post: function($scope, compiledEle){
                            $scope.showAlert = function(){
                                alert("The button is clicked");
                            };
                        }
                    };
                }

            };
        });

还有什么是该范围的方法不会被绑定到在编译阶段添加的按钮,但同样可以在模板/ templateUrl进行绑定,如果我按钮的原因。此外,该方法获取绑定,如果在链接阶段,我们有一个行:

What could be the reason that the scope method doesn't get binded to button added during compile phase, but the same can be binded if I button in the template/templateUrl. Also the method get bind if in the linking phase we include a line:

$编译(compiledEle.contents())($范围内);)

$compile(compiledEle.contents())($scope);)

此外,它会得到绑定的方法的,如果不是在链接阶段加入$ scope.showAlert,我们已经在控制器中的方法!!!

Also it will be get bind to the method if instead of adding "$scope.showAlert" in linking phase , we already have the method in controller !!!

    .controller("ctrl1", function($scope){
                $scope.myModelObj = {
                    name: 'Ratnesh',
                    value: 100
                };
                $scope.showAlert = function(){
                    alert("The button is clicked");
                };
            })

编译的方法是做DOM操作和链接阶段是编译的HTML链接到的范围。因此,我们可以将新元素的DOM编译和新方法的范围过程中链接阶段补充,所以那里是我的期望也越来越错了?

compile method is to do DOM manipulation and linking phase is to link compiled html to scope. So we can add new element to DOM during compile and new scope method in linking phase, so where is my expectation is getting wrong?

推荐答案

的问题是,你的编译函数没有访问元素实例的范围还没有在编译的时刻。

The problem is that your compile function does not have access to the scope of the element instance yet at the moment of compilation.

您想 NG-点击执行实例范围,当模板编译这是没有用的方法。

You want ng-click to execute a method of the instance scope, which is not yet available when the template is compiled.

我添加备注,code说明会发生什么:

I have added comments to the code to illustrate what happens:

app.directive("fromCompile", function($compile) {
  return {
    restrict: 'E',
    scope: {},
    compile: function(tElement) {

      // When AngularJS compiles the template element, it does not have
      // access yet to the scope of the iElement, because the iElement does
      // not exist yet.
      // You want ng-click to execute a method of the iElement scope
      // which does not exist here yet because you are modifying the
      // template element, not the instance element.
      // This will not give you the effect you are looking for because it
      // will execute the function in a scope higher up the scope hierarchy.
      tElement.append('<button ng-click=\"showAlert()\">Using compile: click me (this will not work correctly)</button>');
      return {
        post: function(scope, iElem, iAttrs) {
          scope.showAlert = function() {
            alert("This button was added using compile");
          };
        }
      };
    }
  };
});

要解决这个问题,你既可以使用模板,让AngularJS自动编译模板您:

To solve the problem you can either use a template to let AngularJS automatically compile the template for you:

app.directive("fromTemplate", function($compile) {
  return {
    restrict: 'E',
    scope: {},
    template: "<button ng-click=\"showAlert()\">Using template: click me (this will work)</button>",
    link: function(scope, iElem, iAttrs) {
      scope.showAlert = function() {
        alert("This button was added using template");
      };
    }
  };
});

或者在元素实例的链接功能手动编译模板自己(因为你能在那里访问正确的范围内):

Or compile the template manually yourself in the link function of the element instance (because you can access the correct scope there):

app.directive("fromLink", function($compile) {
  return {
    restrict: 'E',
    scope: {},
    link: function(scope, iElem, iAttrs) {
      var linkFn = $compile("<button ng-click=\"showAlert()\">Using link: click me (this will work)</button>");
      var button = linkFn(scope);
      iElem.append(button);
      scope.showAlert = function() {
        alert("The button was added using $compile in link function");
      };
    }
  };
});

我创建了一个普拉克所有code和工作版本这里

希望帮助!

这篇关于范围不得到与编译阶段增加了新的元素相关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆