2016-03-08 28 views
0

由於對Angular形成驗證的方式感到不滿,我決定實施我自己的解決方案,並遇到了一個讓我難以置信的問題。使用從服務返回的值更新ngModel

我的設置如下:

  1. 一個指令來實例化一個新的形式。
  2. 其控制器訪問相關的表單模式,然後通過ng-repeat用於生成視圖中的字段。
  3. 這些輸入& textarea字段然後通過ng-model綁定到控制器。
  4. 在字段更改或表單提交時,控制器將表單數據發送給驗證服務,如果適用,該驗證服務返回錯誤,然後綁定到DOM。

我遇到了一個問題,試圖在第4部分驗證之前實施衛生步驟。此衛生步驟理論上應使用服務方法的返回值更新控制器數據,更新DOM綁定和允許驗證步驟使用更新的值。儘管控制器值本身正在更新,但此更改未反映在DOM中。

相關的代碼如下:

檢視:

<div ng-repeat="(field, value) in form.schema"> 
    <!-- ... --> 
    <textarea ng-model="form.data[field]" ng-model-options="{ updateOn: 'blur' }" ng-change="form.changed(field)"></textarea> 
    <div class="message">{{ form.errors[field] }}</div> 
</div> 

控制器:

// Controller submit method 
ctrl.submit = function() { 

    var err; 

    for (var field in ctrl.schema) { 
    ctrl.data[field] = validationService.sanitizeField(ctrl.data[field], ctrl.schema[field]); 
    ctrl.errors[field] = validationService.validateField(ctrl.data[field], ctrl.schema[field]); 
    if (ctrl.errors[field] !== undefined) { 
     err = true; 
    } 
    } 

    if (err) { 
    return; 
    } 

    // Proceed ... 

服務:

// Public field sanitation method 
var sanitizeField = function (value, schema) { 
    try { 
    // Try sanitation 
    } 
    catch (e) { 
    // Error 
    } 
    return value; 
} 

記錄新ctrl.data[field]值i在衛生條件下,控制器產生正確的結果。這個結果也被正確地傳遞給後續的validateField方法。但是,新的數據值沒有在DOM中更新。

起初,我想這可能是一個問題,沒有被應用的範圍,或承諾的問題。相應地更新服務&控制器並未解決問題。我也嘗試在一個對象中包裝衛生回報值,但無濟於事。

奇怪的是,將服務中的返回值從value變量更改爲原語(例如, 'test',更新返回的DOM。

同樣,從服務驗證方法返回的錯誤(也包括字符串而不是變量)在DOM中相應地更新。

儘管有大量的搜索,我還沒有找到具體的話題。任何見解都將非常感謝!

回答

1

解決!

Unbeknownst對我,角設有一個ngTrim指令,它被自動綁定到輸入域和是默認設置爲true [Documentation]。

有了這個指令,數據在控制器提交表單時被自動裁剪 - 由我的衛生服務執行的裁剪因此不會改變數據,這反過來不會反映在DOM中因爲Angular沒有采取任何改變。

此行爲可以通過在視圖中的相關字段上設置ng-trim="false"來緩解。

0

嘗試做下面的事情;

for (var field in ctrl.schema) { 
    ctrl.data[field] = angular.copy(validationService.sanitizeField(ctrl.data[field], ctrl.schema[field])); 
    ctrl.errors[field] = angular.copy(validationService.validateField(ctrl.data[field], ctrl.schema[field])); 
    if (ctrl.errors[field] !== undefined) { 
     err = true; 
    } 
    } 

當涉及到使用嵌套屬性更新對象/數組時,角度是棘手的。您可以使用$scope.$watchCollection來確保對象/數組已更新,或者您可以使用angular.copy(),這將確保DOM更新。

+0

恐怕不行!通過'angular.copy()'運行sanitizeField結果不會改變任何內容,並且指定'ctrl.data [field]'作爲可選的目標參數會產生一個'不能複製!來源和目的地是相同的錯誤:( –