使用指令绑定属性

时间:2016-07-02 20:05:32

标签: angularjs svg angularjs-directive typescript

我正在尝试使用Angular和TypeScript更改内联SVG中属性的填充颜色。这个想法是SVG具有“TA”属性;任何svg元素与这些“TA”attriubtes之一,我想改变填充颜色从下拉列表绑定到用户定义的颜色。但是,我很难弄清楚如何将此属性更改为动态绑定。

以下是我尝试这样做的方法:

export class TaDirective implements ng.IDirective {

static create_instance() : ng.IDirective {
    return new TaDirective();
}

constructor(){
}

public bindToController = true;
public controllerAs = "ctrl";
public scope = { name: '=' };

public compile(element: ng.IAugmentedJQuery, attrs: ng.IAttributes, transclude: ng.ITranscludeFunction) {
    var ta = attrs.$attr["ta"] as string

    var ele = element[0];
    attrs.$set

    // Make all visable (works as expected)
    attrs.$set('visibility', "visible")

    // Attempt to bind to the controller's fill
    attrs.$set('fill', "{{ ctrl.fill }}")
    //attrs.$set('fill', 'cyan') // Verify idea works
}

public link(scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, controller: any, transclude: ng.ITranscludeFunction) {
    //Tried code here
}


public controller(scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes){
    // Tried code here
}

}
app.directive('ta', TaDirective.create_instance);

以下是带有TypeScript和编译JavaScript的Plunker

修改 所以我想出了如何做到但它仍然不优雅,因为范围的名称是硬编码的。我愿意接受如何解耦为两个的建议。 (Plunker也更新了)

export class TaDirective implements ng.IDirective {
    static create_instance() : ng.IDirective {
        return new TaDirective();
    }

    constructor(){
    }

    public link(scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, controller: any, transclude: ng.ITranscludeFunction) {
        var ta = attrs.$attr["ta"] as string

        var ele = element[0];

        // Make all visable
        attrs.$set('visibility', "visible")

        // Attempt to bind to the controller's fill
        scope.$watch('vm.fill', function(newFill) {
            attrs.$set('fill', newFill)
        })
    }
}

1 个答案:

答案 0 :(得分:1)

将控制器与指令监视表达式分离的一种常见做法是改为观察指定的属性。

而不是以下内容:

JS:

scope.$watch('vm.fill', function (fill) {
    attrs.$set('fill', fill);
});

HTML:

<text ta="1">Text</text>

你应该:

JS:

scope.$watch(attrs.ta, (fill: string): void => {
    attrs.$set('fill', fill);
});

HTML:

<text ta="vm.fill">Text</text>

这种做法可确保您的指令更具可伸缩性,因为vm.fill监视表达式未绑定到指令链接函数,而是通过角度模板传递给指令。 Here is an updated plunkr