[英]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.