基本用法
通過bower安裝之后,將schemaForm模塊載入到模塊定義中,fuse中安裝第三方包需要在app/core/core.module.js中聲明。
然后在controller里面,將schema、form、model屬性賦給$scope,schema定義了數據結構,form定義了UI,model綁定了用戶的輸入。
angular.module('myModule', ['schemaForm']) .controller('FormController', function($scope) { $scope.schema = { type: "object", properties: { name: { type: "string", minLength: 2, title: "Name", description: "Name or alias" }, title: { type: "string", enum: ['dr','jr','sir','mrs','mr','NaN','dj'] } }, "required": ["name"] // 定義強制字段 }; // 表單字段定義 $scope.form = [ { key: "name", validationMessage: { 200: 'Seriously? Value {{value}} totally shorter than {{schema.minLength}}, which is NOT OK.', 302: "This field is like, uh, required?" } }, "title", { type: "submit", title: "Save" } ]; // 定義表單各個域以及他們的行為(錯誤信息、提交按鈕等) $scope.model = {}; // 用戶的輸入綁定到這里 });
然后在模板中,通過ng-controller載入,使用sf-schema、sf-form、sf-model指令。
<div ng-controller="FormController"> <form sf-schema="schema" sf-form="form" sf-model="model"></form> </div>
sf-schema指令不一定要在form標簽中,實際上可以放在一個div中,比如需要有一個自己編寫的按鈕或表單域。
處理提交
Schema Form並不在意你怎么處理你的數據,處理提交最推薦的方式是使用ng-submit指令,同時建議用name屬性從而可以在FormController中訪問到它,並且驗證合法性。
你可以通過broadcast一個事件(schemaFormValidate)來強制執行校驗。
$scope.onSubmit = function(form) { // First we broadcast an event so all fields validate themselves $scope.$broadcast('schemaFormValidate'); // Then we check if the form is valid if (form.$valid) { // ... do whatever you need to do with your data. } }
關於$scope.$broadcast的用法參考stackoverflow
表單更新
Schema Form監聽sf-form和sf-schema,當他們改變的時候會重畫整個表單,但也不是完全改變(……不知道文檔這里在講什么)
如果想要手動更新表單,可以調用schemaFormRedraw事件。
function Ctrl($scope) { $scope.removeLastField = function() { $scope.form.pop() $scope.$broadcast('schemaFormRedraw') } }
全局屬性
Schema Form通過sf-options來設定全局屬性,sf-options應該和sf-schema放在一起。它接收一個對象,有以下屬性和取值。
屬性 | 類型 | 描述 |
supressPropertyTitles | boolean | 默認下沒有設置schema的title時,會用它的名字作為title,將本屬性設為true會取消這個默認行為 |
formDefaults | object | 一個對象,定義到所有的表單項中 |
validationMessage | object or function | |
setSchemaDefaults | boolean | |
destroyStrategy | string | |
pristine | Object {errors, success} | |
validateOnRender | boolean |
formDefaults屬性最常用的是設置ngModelOptions,以下設置會使表單的每項都帶上一個屬性:ng-model-options="form.ngModelOptions"
<div ng-controller="FormController"> <form sf-schema="schema" sf-form="form" sf-model="model" sf-options="{ formDefaults: { ngModelOptions: { updateOn: 'blur' } }}"></form> </div>
關於ng-model-options:常用於將“model與用戶輸入實時同步”改為“model在用戶輸入完(blur之后)再同步”。參看文檔
校驗信息
Schema Form使用tv4來校驗表單。以下幾個方法可以改變默認的校驗信息:
- 改變sfErrorMessages的默認值(通過其provider),這會將校驗信息設置到sf-schema的所有實例中。
- 用全局屬性validationMessage
- 用表單域屬性validationMessage
如果一個定義好的驗證錯誤代碼在表單域屬性中找不到,schema form會找全局屬性,如果沒有則用它的默認值(不知道文檔在說什么……)
錯誤的類型是通過匹配tv4的錯誤碼
信息插入
通過value、shcema等變量可以讀取到用戶輸入的值,以及schema中定義的值,從而使得錯誤信息動態變化。(error:錯誤類型碼,這個應該也常用,比如說定義好一個錯誤信息的數組errorMessage[],通過errorMessage[error]就能讀取對應的錯誤信息。)
$scope.form = [ { key: "name", validationMessage: { 200: 'Seriously? Value {{value}} totally shorter than {{schema.minLength}}, which is NOT OK.', 302: "This field is like, uh, required?" } }, "title", { type: "submit", title: "Save" } ];
*這里的{{value}}並不能正常顯示用戶的輸入,待解決。
自定義校驗
有一些需要后端協助的校驗。Schema Form允許我們注入任意的校驗信息到任意的表單域中。
這是通過schemaForm.error事件開始,然后在表單域的key結束。它需要兩個參數,第一個是錯誤碼/錯誤名,第二個是校驗信息/布爾值。使用的是$scope.$broadcast。
例子:在后台校驗發現用戶名重復時,調用以下語句可以讓表單不合法,並顯示信息:
$scope.$broadcast('schemaForm.error.name','usernameAlreadyTaken','The username is already taken');
如果后台校驗發現用戶名可以使用,調用以下語句可以讓表單合法,這時第二個參數要為true:
$scope.$broadcast('schemaForm.error.name','usernameAlreadyTaken',true);
使用ngModelController
另一個校驗表單的方法是使用ngModelController,Schema Form可以將ngModelController暴露在一個表單域中,給一個定義了表單的函數(……又不知道在說什么)。或者你可以用一個shorthand,就是通過加$validators和$asyncValidators。
我的簡單理解:就是$validators和$asyncValidators都是用函數來進行校驗,區別是一個是同步的一個是異步的,下面是$asyncValidators的例子:
$scope.form = [ { key: 'name', placeholder: 'Anything but "Bob"', $asyncValidators: { 'async': function(name) { var deferred = $q.defer(); $timeout(function(){ if (angular.isString(name) && name.toLowerCase().indexOf('bob') !== -1) { deferred.reject(); } else { deferred.resolve(); } }, 1500); return deferred.promise; } }, validationMessage: { 'async': "Wooohoo thats not an OK name!" } }, .... ];
上面的代碼會在輸入name表單域時,經過1.5秒后校驗用戶的輸入是不是bob(忽略大小寫)
表單的默認schema
比較推薦的做法是將表單元素的UI和驗證分開,但是如果確實需要在schema中定義表單元素的UI,則可以通過x-schema-form屬性來進行設置。x-schema-form需要是一個對象。
{ "type": "object", "properties": { "comment": { "type": "string", "title": "Comment", "x-schema-form": { "type": "textarea", "placeholder": "Don't hold back" } } } }
默認表單type
在schema定義表單的type,對應生成的表單的類型如下表。
Form定義
form的定義有三種形式:
- 星號"*",代表整個schema都使用默認形式
- 一個字符串,標識屬性名:"name"
- 一個對象,定義了表單的各種屬性(placeholder、校驗信息等等):{ key: "name" , ... }
另外在$scope.form中可以重寫表單域的順序和它的type。
$scope.schema = { "type": "object", "properties": { "surname": { "type": "string" }, "firstname": { "type": "string" }, } }; $scope.form = [ "firstname", { key: "surname", type: "select", titleMap: [ { value: "Andersson", name: "Andersson" }, { value: "Johansson", name: "Johansson" }, { value: "other", name: "Something else..."} ] } ];