在測試過程中,我發現我們在此表單輸入的模型上有一個$scope.watch
。事實證明,手錶功能將運行三次 - 第一次,具有正確的對象值;第二次用字符串「Object object」作爲對象的表示;第三次,空值。我通過檢查newValue
數據類型對此進行了修復 - 如果它是一個字符串,則將模型重置爲舊值。然而,儘管這很有效,但我仍然不確定爲什麼簡單地改變圖書館會導致這樣的迴歸。
如果我有時間,我打算嘗試用簡化的測試用例來重現這一點。
更新2:我發現this question,這解釋了這不起作用的根本原因。因此,看起來可以在指令上設置優先級並調用渲染函數。
代碼會像這樣:
angular.module('ui.select2', []).value('uiSelect2Config', {}).directive('uiSelect2', ['uiSelect2Config', '$timeout',
function (uiSelect2Config, $timeout) {
var options = {};
if (uiSelect2Config) {
angular.extend(options, uiSelect2Config);
}
return {
require: 'ngModel',
priority: 1, // This fixed it.
compile: function (tElm, tAttrs) {
......
我們用這個在我們的解決方案,雖然它並不完美(仍然有一些打嗝有數據綁定在某些情況下,選擇二愛,而不是返回對象的字符串出於某種原因),我們已經能夠使其工作。
更新:我想我在AngularUI的select2.js中發現了潛在的問題。
的source code下面定義的指令進行選擇2的一部分convertToSelect2Model
下:
if (controller) {
// Watch the model for programmatic changes
scope.$watch(tAttrs.ngModel, function (current, old) {
if (!current) {
return;
}
if (current === old) {
return;
}
controller.$render();
}, true);
controller.$render = function() {
if (isSelect) {
elm.select2('val', controller.$viewValue);
} else {
if (opts.multiple) {
var viewValue = controller.$viewValue;
if (angular.isString(viewValue)) {
viewValue = viewValue.split(',');
}
elm.select2(
'data', convertToSelect2Model(viewValue));
} else {
if (angular.isObject(controller.$viewValue)) {
elm.select2('data', controller.$viewValue);
} else if (!controller.$viewValue) {
elm.select2('data', null);
} else {
elm.select2('val', controller.$viewValue);
}
}
}
};
這是一切都在老版本的角度好。但是,在Angular 1.2.5中,這是行不通的;該函數實際上已經由Angular定義,因此寫函數從不會被調用。將controller.$render
函數重命名爲controller.$renderui
修復了潛在的問題。這是我的解決辦法:
if (controller) {
controller.$renderui = function() {
if (isSelect) {
elm.select2('val', controller.$viewValue);
} else {
if (opts.multiple) {
elm.select2(
'data', convertToSelect2Model(controller.$viewValue));
} else {
if (angular.isObject(controller.$viewValue)) {
elm.select2('data', controller.$viewValue);
} else if (!controller.$viewValue) {
elm.select2('data', null);
} else {
elm.select2('val', controller.$viewValue);
}
}
}
};
// Watch the model for programmatic changes
scope.$watch(tAttrs.ngModel, function (current, old) {
if (!current) {
return
}
if (current == old) {
return
}
controller.$renderui();
}, true)
這個固定了很多,我有選擇二跑進問題(在我的項目中使用),並結合到NG-模型(和現在一樣,選擇二將正確更新時NG-模型更改),包括我原來的問題。
TLDR:AngularUI select2嘗試定義controller.$render
,但該函數已由Angular 1.2.5內部定義,並試圖重新定義它似乎不起作用。重命名函數似乎可以解決問題。
我希望這可以幫助別人。