AngularJs将复杂数据传递给指令


76

我有以下指令:

<div teamspeak details="{{data.details}}"></div>

这是对象结构:

data: {
                details: {
                    serverName: { type: 'text', value: 'my server name' },
                    port: { type: 'number', value: 'my port' },
                    nickname: { type: 'text' },
                    password: { type: 'password' },
                    channel: { type: 'text' },
                    channelPassword: { type: 'password' },
                    autoBookmarkAdd: { type: 'checkbox' }
                }
}

我希望它根据data.details对象内部的数据生成一个链接。 不幸的是,由于我无法以某种方式访问​​该details对象的任何内部值,因此它不起作用,但是如果我将其传递给一个简单的数据结构,例如:

<div teamspeak details="{{data.details.serverName.value}}"></div>

我可以使用访问它{{details}}

这是我的指令代码:

App.directive('teamspeak', function () {
    return {
        restrict: 'A',
        template: "<a href='ts3server://{{details.serverName.value}}:{{details.port.value}}'>Teamspeak Server</a>",
        scope: {
            details: '@details',
        },
        link: function (scope, element, attrs) {
        }
    };
});

谢谢

Answers:


106

Angularjs官方网站上阅读说明:

@或@attr-将本地范围属性绑定到DOM属性的值。由于DOM属性是字符串,因此结果始终是字符串。如果未指定attr名称,则假定属性名称与本地名称相同。给定范围的小部件定义:{localName:'@ myAttr'},则小部件范围属性localName将反映您好{{name}}的插值。随着name属性的更改,小部件作用域上的localName属性也会更改。从父作用域(而不是组件作用域)中读取名称。

因此,您只能发送一个字符串,以传递一个对象,您需要使用建立双向绑定=

   scope: {
        details: '=',
    },

您的HTML看起来像

<div teamspeak details="data.details"></div>

2
这似乎不适用于TypeScript。我所做的是创建一个定义范围的接口。在该界面中,我有一个自定义对象。将接口分配给作用域时,我不能这样做object = '=',因为您不能将字符串分配给type对象ObjectType。关于如何使用TypeScript做到这一点的任何建议?
bilo-io

也可以使用绑定来完成:{}我将在工作后答复:)
Sonic Soul

39

有人问到如何在不隔离范围的情况下做到这一点,这是一个解决方案:

<div teamspeak details="{{data.details}}"></div>

App.directive('teamspeak', function () {
    return {
        restrict: 'A',
        template: "<a href='ts3server://{{details.serverName.value}}:{{details.port.value}}'>Teamspeak Server</a>",
        link: function (scope, element, attrs) {
            if(attrs.details){
                scope.details = scope.$eval(attrs.details);
            }
        }
    };
});

我们甚至可以使用$interpolate是否attrs.details应使用成角的{{......}}表达式来动态设置其中的值...

scope.details = scope.$eval($interpolate(attrs.details)(scope));

(不要忘记将$interpolate服务注入您的指令中)

重要说明: 我尚未使用角度2测试此方法。


1
如果使用attrs,则将很难将该指令转换为angular2。这只是个人提示。
Peter Huang

谢谢@ sh977218,我加了一条笔记,该方法未使用角度2进行测试
plong0
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.