簡體   English   中英

AngularJS中的動態表單

[英]Dynamic form in AngularJS

我正在為客戶開發CMS,它全部基於AngularJS及其控制器,視圖,服務等。

我需要的是一種模式,其中動態加載的腳本在現有范圍內注入一些數據

好吧,用人類的話來說: 我有一個由控制器管理的表單 該表格有幾個預設字段。 這些字段由范圍數組管理,例如:

$scope.fields = [
  { type: "text", name="first_name" },
  { type: "text", name="last_name" },
  { type: "email", name="email" }
];

該視圖動態打印字段(即是腳手架)。

當客戶登錄到應用程序時,我檢查他的個人資料中是否有要加載的自定義腳本,如果是,則應用程序將javascript附加到DOM,則javascript文件名等於登錄用戶的用戶名。

因此,如果用戶被稱為“ darko ”,並且啟用了自定義腳本,則應用程序將此文件附加到DOM:

/js/customers/darko.js

假設darko在表單中還有其他字段要顯示(並保存) ,我該怎么做? 我需要鈎住控制器,以便可以訪問其作用域,然后注入字段。 就像是:

var $scope = getUserFormScope();//some magic....
$scope.fields.push({ type: "text", name="skype" });

但是,帶有更多字段的表單僅是示例,更確切地說,我真正需要的是一種“掛鈎控制器”並可以訪問其作用域的方法。

任何想法?

我終於使用了marfarma建議的方法。 自定義腳本包含一個或多個部分控制器,這些控制器的名稱與要擴展的自定義字詞前綴相同,然后使用這些部分控制器擴展我的控制器。 例如,我的應用程序有一個名為PageController的控制器,在此控制器內,我檢查CustomPageController是否存在:

if (typeof CustomPageController == 'function') {
    angular.extend(this, CustomPageController($scope));
}

如果是這樣,我將使用自定義控制器擴展主控制器。

這是“鈎子控制器”並可以訪問其作用域的一種通用方法-通過angular.extend混合鈎子代碼。

function CustomUserController($scope) {
    // contents of this hook controller is up to you

    var _this = this;

    // Mixin instance properties.
    this.vocalization = getValue('vocalization',$scope.user);
    this.runSpeed = getValue('runSpeed'        ,$scope.user);

    // Mixin instance methods.
    this.vocalize = function () {
        console.log(this.vocalization);
    };

    // Mixin scope properties.
    $scope.color = color;

    // Mixin scope methods.
    $scope.run = function(){
        console.log("run speed: " + _this.runSpeed );
    };
}

function PageController($scope) {

    var _this = this;
    $scope.user; // this should be the current user obj, with key for custom script lookup

    // Mixin Custom Script into Controller.
    if (userService.hasCustomScript($scope.user)) {
        angular.extend(this, new CustomUserController($scope));
    }
}

對於您的特定示例,將任意字段插入表單的一種方法是動態構建它。 我使用了一種可能適合您情況的架構表單指令。 給定一個定義模型屬性的模式,以及一個指定項目包含順序的數組,該指令對表單進行布局。

例如(另請參見此工作的插件,包括add'l features ):

<form class="form-inline" name="form" novalidate role="form">
    <div class="row-fluid clearfix">
        <h2>Sample Form</h2>
    </div>
    <div class="row-fluid clearfix">
        <hr> 
        <div class="span12">
            <fieldset class="span6">
                <schema-form-fields
                    fields="side1Fields"
                    model="model"
                    schema="modelSchema"
                    data="requestResult"
                    schema-list="schema">
                </schema-form-fields>
            </fieldset>
            <fieldset class="span6">
                <schema-form-fields
                    fields="side2Fields"
                    model="model"
                    schema="modelSchema"
                    data="requestResult"
                    schema-list="schema">
                </schema-form-fields>
            </fieldset>
        </div>
    </div>
    <div class="row-fluid clearfix">
        <button
            class="btn btn-primary span2 offset10"
            type="submit">
            Submit
        </button>
    </div>
</form>
// example controller with dynamic form
app.controller('HomeCtrl', ['$scope', 'schema', 'requestResult', 'dataService',
    function($scope, schema, requestResult, dataService) {

        $scope.modelSchema = schema.product;          
        $scope.model = {
            factoryDate: '20160506'
        };

        // field name arrays - one array per column in sample layout
        // insert elements into these and form should re-render
        // may require explicit watch to trigger update
        $scope.side1Fields = [
            'productName',
            'factoryDate'
        ];

        $scope.side2Fields = [
            'productType',
            'timeValue'
        ];  

        // ....  other controller code    
    }
]);
// example schema
app.value('schema', {
    "product": {
        "type": "object",
        "title": "Product Schema",
        "properties": {
            "productType": {
                "type": "string",
                "title": "Product Type",
                "showLabel": true,
                "tooltip": "Product classification",
                "readonly": false,
                "required": true,
                "class": "custom-select",
                "enum": ['Bike', 'Car', 'Airplane', 'Glider', 'Stilts']
            },
            "productName": {
                "title": "Product Name",
                "showLabel": true,
                "type": "string",
                "tooltip": "A more descriptive name for the modeled structure.",
                "readonly": false,
                "required": true
            },
            "factoryDate": {
                "title": "Factory Date",
                "type": "string",
                "showLabel": true,
                "control": "date",
                "dateFormat": "yyyymmdd",  // TODO format as provided 
                "tooltip": "Date of manufacture.",
                "dateOptions": {
                    autoclose: true
                },
                "readonly": false,
                "required": true
            },
            "timeValue": {
                "title": "Time (HHMM)",
                "showLabel": true,
                "type": "string",
                "pattern": "([0-1]{1}[0-9]{1}|20|21|22|23)[0-5]{1}[0-9]{1}",
                "timeFormat": "hhmm",  // TODO format as provided 
                "tooltip": "Time entry.",
                "readonly": false,
                "required": true,
            }
        }
    }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM