AngularJS 表单模板

AngularJS template for form

我正在编写一个 AngularJS 应用程序,但我正在努力使其模块化。

我有一个包含大量输入的表单。对于每一个,我都必须重复很多代码。这是一个例子:

<div class="row">
    <div class="col-lg-6 col-lg-offset-3
            col-md-6 col-md-offset-3
            col-sm-12 col-xs-12">
        <div class="input-group">
            <span class="input-group-addon">Device Category</span>
            <input 
                type="text"
                class="form-control"
                autocomplete="off"
                ng-model="device.category"
            >
        </div>
    </div>
</div>

<div class="row">
    <div class="col-lg-6 col-lg-offset-3
            col-md-6 col-md-offset-3
            col-sm-12 col-xs-12">
        <div class="input-group">
            <span class="input-group-addon">Device Template</span>
            <select 
                class="form-control"
                ng-model="device.characteristics"
                ng-change="copyDeviceTemplate(device)"
                ng-options="opt as opt.label for opt in templateDevices"
            >
            </select>
        </div>
    </div>
</div>

如您所见,重复了很多代码。因此,我考虑创建自己的指令。如果成功,上面的两个例子在HTML中写成如下:

<div device-input label="Device Category">
    <input 
        type="text"
        class="form-control"
        autocomplete="off"
        ng-model="device.category"
    >
</div>

<div device-input label="Device Template">
    <select 
        class="form-control"
        ng-model="device.characteristics"
        ng-change="deepCopyDeviceTemplate(device)"
        ng-options="opt as opt.label for opt in templateDevices"
    >
    </select>
</div>

问题是我无法理解如何使这样的指令起作用。我只有这个:

angular.module("myApp").directive('deviceInput', [ function () {
    return function(scope, element, attributes) {

        var label = attributes['label'];

        var htmlText = '<div class="row">' + 
            '<div class="col-lg-6 col-lg-offset-3 col-md-6 col-md-offset-3 col-sm-12 col-xs-12">' + 
            '<div class="input-group">' + 
            '<span class="input-group-addon">' + label + '</span>' + 

            // Something here to add whatever is inside the <device-input> div

            '</div></div></div>';

        element.replaceWith( htmlText );
    };
}]);

这就是我想做的,但我不知道如何添加设备输入中的任何内容。你有什么建议吗?有没有更好的方法来实现这一目标?

您想使用嵌入将指令的子元素动态移动到模板中。理想情况下,我会将 HTML 模板也放入一个单独的文件中。

试试这个:

angular.module("myApp").directive('deviceInput', [ function () {
    return {
        replace: true,
        transclude: true,
        // Use scope true to make a copy of the parent scope, so you still have access to all parent scope values
        scope: true,
        template: function($element, $attrs) {
            var template = '<div class="row">' + 
                '<div class="col-lg-6 col-lg-offset-3 col-md-6 col-md-offset-3 col-sm-12 col-xs-12">' + 
                '<div class="input-group">' + 
                // Probably eventually want to use {{label | translate}} to localize this value, then the the `label` on the directive would pass in the translation key instead of the value.
                '<span class="input-group-addon">{{label}}</span>' + 
                // Transclusion moves the child content of the directive here
                '<div ng-transclude></div>' +
            '</div></div></div>';
            return template;
        },
        link: function(scope, element, attrs) {
            scope.label = attrs.label;
        }
    }
}]);