AngularJS中的AngularJS自定义指令具有动态属性和双向绑定

时间:2014-10-31 21:52:50

标签: angularjs angularjs-directive model-binding nested-loops

我在这上面撞墙已经好几天了,最后决定发布这个问题,因为我找不到符合我要做的答案。

上下文:我正在构建一个动态表单构建平台,用于描述JSON结构中的表单元素 -

    {
        "name": "email",
        "type": "email",
        "text": "Your Email",
        "model": "user.profile.email"
    } 

然后在视图中我有一个递归的ng-repeat,包括像这样的字段模板 -

<script type="text/ng-template" id="field.html">
    <div ng-if="field.type === 'email'" class="{{field.class}}">
        <p translate="{{field.text}}"></p>
        <input type="{{field.type}}" name="{{field.name}}" class="form-control" dyn-model="{{field.model}}">
    </div>
</script>

如您所见,我使用自定义指令dynModel来创建ng-model属性,其中包含来自字符串值的模型的插值。到目前为止做得很好。

现在我有一个更复杂的场景,其中我有一组字段可以通过单击Add按钮或removeMe按钮添加或删除。见下文 -

         {
            "name": "urls",
            "type": "collection",
            "text": "Your Profile URLs",
            "model": "user.profile.urls",
            "items": [
                {
                    "name": "url",
                    "type": "url",
                    "text": "Facebook URL",
                    "model": "url"
                },
                {
                    "name": "url",
                    "type": "url",
                    "text": "Facebook URL",
                    "model": "url"
                }
            ],
            "action_button": {
                "name": "add",
                "type": "action",
                "action": "addURL"
            }
      }

 <div ng-if="field.type === 'collection'">
    <button class="btn btn-info"  dyn-click click-action="{{field.action_button.action}}" click-model="{{field.model}}">{{field.action_button.text}}</button>
     <div dyn-ng-repeat="item in {{field.model}}" >
        <div ng-repeat="field in field.items" ng-include src="'field.html'"></div>
     </div>
</div>

正如您将注意到的,我有另一个自定义指令,负责从前一个ng-repeat(未显示)中插入{{field.model}}。

现在问题的关键。正如您在模板中看到的,我有嵌套的ng-repeats,第一个遍历user.profile.urls,第二个迭代JSON中的字段参数并创建HTML标记等。其中一个字段是按钮(action_button),用于向列表中添加更多URL。当我单击按钮时,我希望它在我的控制器中触发一个函数,并有效地将一个新子项添加到父模型(user.profile.urls)。然后,我还希望每个URL,现有的和新的都有一个移动按钮,它们将是动态的,并将从模型中删除该特定项目。

如果你看到上面的代码,我有一个自定义指令dyn-click,它读入

click-action="{{field.action_button.action}}" 

包含要在我的控制器中驻留的函数名称(addURL)和模型

click-model="{{field.model}}"

(user.profile.urls)要添加新项目。这不起作用。这种复杂性的原因是我有多级嵌套,并且在每个级别都有需要插值和绑定的动态元素。指令dyn-click现在看起来像这样 -

exports = module.exports = function (ngModule) {
    ngModule.directive("dynClick",function() {
        return {
            restrict: 'A',  
            link: function(scope,element,attrs) {
                $(element).click(function(e, rowid){
                    scope.clickAction(scope.clickModel, scope.$index);
                });
            }
        };
    });
};

使用此代码,当我单击渲染表单的“添加”按钮时,上面的$(element).click方法中的代码将被执行,从而产生以下错误 -

未捕获的TypeError:undefined不是函数

我在dyn-click指令中使用范围:{}尝试了一些不同的东西,它们具有不同的错误,并且没有一个完全使用模型的双向绑定并按预期调用函数。

帮助!

EDIT-1 - 请参阅评论:

        $(element).click(function(e, rowid){
            scope.$eval(attrs["clickAction"])(scope.$eval(attrs["clickModel"]), scope.$index);
        });

EDIT-2:这里的掠夺者 - http://plnkr.co/edit/DoacjRnO61g4IYodPwWu?p=preview。仍然调整它以使其正确,但你们应该能够看到必要的部分。谢谢!

EDIT-3:谢谢塞巴斯蒂安。新的掠夺者在这里 - http://plnkr.co/edit/Z6ViT7scubMxa17SFgtx?p=preview。 field.items ng-repeat的问题仍然存在。由于某种原因,内部ng-repeat没有被执行。有任何想法吗?何塞普,塞巴斯蒂安?

0 个答案:

没有答案