AngularJS - 向指令的隔离范围添加新值

时间:2014-11-08 17:49:05

标签: angularjs

我有一个带有隔离范围的指令如下:

    application.directive("myDirective",function(){
        return {
            restrict: "A",
            scope: {myDirective:"="},
            link : function(scope) {
                console.log("My directive: ",scope.myDirective) // works fine
                scope.person={name:"John",surname:"Doe"}

                scope.hello=function(){
                    console.log("Hello world!")
                }
            }
        }
    })

对应观点:

<div my-directive='{testValue:3}'>
    Testvalue: {{myDirective}}<br/>
    Hello {{person}}
    <button ng-click="hello()">Say hello</button>
</div>

似乎我不能使用范围中声明的任何字段。鉴于&#34; myDirecive&#34;和&#34;人&#34;字段是空白的,范围&#34;你好&#34;按下按钮时不执行功能。

当我通过scope =&#34; true&#34;指令,但在隔离范围内不起作用。

我在这里遗漏了什么或者没有办法将变量引入指令的孤立范围?

更新

更新了问题,说明为什么我宁愿不使用静态模板。我想要实现的效果是make指令允许上传任何html表单通过rest / json获取表单初始数据。整个过程相当复杂且特定于应用程序,因此我无法使用任何可用的表单库。我在下面介绍用例的简化版本:

更新的指令

    application.directive("myForm",function(){
        return {
            restrict: "A",
            scope: {myForm:"="},
            link : function(scope) {
                console.log("Form parameters: ",scope.myForm) // works fine
                scope.formData=... // Get form initial data as JSON from server

                scope.submitForm=function(){
                   // Send scope.formData via REST to the server
                }
            }
        }
    })

我想使用此表单的情况。当然,我想用不同的形式多次使用这个指令。

<form my-form='{postUrl:'/myPostUrl',getFormDataUrl:'/url/to/some/json}'>
    <div>Form user: {{formData.userName}} {{formData.userSurname}}
    <input type="text" ng-model="formData.userAge" />
    <input type="text" ng-model="formData.userEmail" />
    <button ng-click="submitForm()">Submit</button>
</form>

我希望这能解释为什么我不能在这个场景中使用一个静态html模板。

也许有人可以解释为什么这适用于范围=&#34; true&#34;并且使用隔离范围我无法访问任何范围变量?

2 个答案:

答案 0 :(得分:1)

使用Angular,指令可以使用template(或templateUrl)或使用已转换的内容。

如果您正在使用模板,则模板可以访问隔离范围。因此,如果您将{{person}}放在模板中,它将按预期工作。

如果您正在使用已转换的内容(即,将该指令应用于该节点的子节点的内容),那么您不仅需要设置transclude: true并指定位置在模板中,被抄除的内容 - 例如<div ng-transclude></div>甚至看到内容,你也不会得到你期望的结果,因为被抄除的内容可以访问与指令的父级相同的范围变量,而不是那些可用于孤立范围的内容。指令。

此外,您应该知道,如果您将一个不可分配的对象传递给指令的隔离范围,并使用&#34; =&#34; - 就像你对my-directive="{testValue: 3"所做的那样,那么你就不能对它进行任何改变(不幸的是,即使它们是范围变量,甚至也属于它的属性)。

因此,为了使您的具体案例有效,请执行以下操作:

application.directive("myDirective",function(){
  return {
    ...
    template: "Testvalue: {{myDirective}}<br/> " + 
              "Hello {{person}} " + 
              "<button ng-click="hello()">Say hello</button>";
  };
});

和相应的观点:

其中prop在视图控制器中设置为:$scope.prop = {testValue: 3};

答案 1 :(得分:0)

您可以随时更改已转换范围的默认行为(但我不推荐):

application.directive("myDirective",function(){
  return {
    tranclude: true,
    scope: {myDirective:"="},
    link : function(scope, element, attrs, ctrl, $transclude) {

      $transclude(scope, function(clone) {
        element.empty();
        element.append(clone);
      });

      scope.person={name:"John",surname:"Doe"};

      scope.hello=function(){
        console.log("Hello world!");
      };
    }
  };
});

请参阅文档:https://docs.angularjs.org/api/ng/service/$compile#transclusion-functions

另请参阅ngTranslude源代码:https://github.com/angular/angular.js/blob/master/src/ng/directive/ngTransclude.js