これは私のHTMLです。
<input id="selectedDueDate" type="text" ng-model="selectedDate" />
ボックスに入力すると、モデルは双方向バインディングメカニズムを介して更新されます。甘い。
しかし、JQueryを介してこれを行うと...
$('#selectedDueDate').val(dateText);
モデルは更新されません。どうして?
これは私のHTMLです。
<input id="selectedDueDate" type="text" ng-model="selectedDate" />
ボックスに入力すると、モデルは双方向バインディングメカニズムを介して更新されます。甘い。
しかし、JQueryを介してこれを行うと...
$('#selectedDueDate').val(dateText);
モデルは更新されません。どうして?
回答:
Angularはその変化を知りません。これについては、を呼び出す$scope.$digest()
か、の内部で変更を行う必要があります$scope.$apply()
。
$scope.$apply(function() {
// every changes goes here
$('#selectedDueDate').val(dateText);
});
ダーティーチェックをよりよく理解するためにこれを見てください
更新:ここに例があります
function
。引数として関数を渡して$ scope。$ applyを呼び出す必要があります。また、$ select内で$ scopeを変更する場合は、$ applyを呼び出す必要があります。ああ、私はあなたが例のためだけにDOM操作をコントローラーの内部に置くことを期待しています、実際のアプリではこれは間違っています;)
datepicker="scopeKeyThatYouWant"
入力で何度でも使用できます
使用するだけです。
$('#selectedDueDate').val(dateText).trigger('input');
trigger('input')
では日付ピッカーを使用しましたonSelect
。値を正しく更新します。
.val('something'
呼び出しを$apply
(または$digest
後で呼び出す)でラップしても機能しませんでした。
$('#selectedDueDate').val(dateText).trigger('change');
うまくいかなかったものを使っていました。.trigger('input');
魔法のように動作します
スコープに対して変数を直接配置しない場合、より確実に更新されることがわかりました。
いくつかの「dateObj.selectedDate」を使用してみて、コントローラーでselectedDateをdateObjオブジェクトに追加します。
$scope.dateObj = {selectedDate: new Date()}
これでうまくいきました。
Angularの範囲外で何が起こっても、Angularはそれを知ることはありません。
ダイジェストサイクルは、モデル->コントローラー、次にコントローラー->モデルからの変更を反映します。
最新のモデルを表示する必要がある場合は、ダイジェストサイクルをトリガーする必要があります
ただし、ダイジェストサイクルが進行中の可能性があるため、サイクルを確認して初期化する必要があります。
できれば、常に安全な申請を行ってください。
$scope.safeApply = function(fn) {
if (this.$root) {
var phase = this.$root.$$phase;
if (phase == '$apply' || phase == '$digest') {
if (fn && (typeof (fn) === 'function')) {
fn();
}
} else {
this.$apply(fn);
}
}
};
$scope.safeApply(function(){
// your function here.
});
AngularJSは文字列、数値、ブール値を値で渡し、配列とオブジェクトを参照で渡します。したがって、空のオブジェクトを作成して、日付をそのオブジェクトのプロパティにすることができます。このようにして、angularはモデルの変更を検出します。
コントローラ内
app.module('yourModule').controller('yourController',function($scope){
$scope.vm={selectedDate:''}
});
HTMLで
<div ng-controller="yourController">
<input id="selectedDueDate" type="text" ng-model="vm.selectedDate" />
</div>
ng-modelは入力イベントをリッスンし、スコープが更新されるため、入力要素の変更イベントをトリガーする必要があります。ただし、通常のjQueryトリガーは機能しませんでした。しかし、これは魅力のように機能するものです
$("#myInput")[0].dispatchEvent(new Event("input", { bubbles: true })); //Works
フォローできませんでした
$("#myInput").trigger("change"); // Did't work for me
合成イベントの作成とディスパッチについて詳しくは、こちらをご覧ください。
.val(value)
存在する場合、角度要素を更新するためにすべての呼び出しを行うjQuery用のこの小さなプラグインを作成しました。
(function($, ng) {
'use strict';
var $val = $.fn.val; // save original jQuery function
// override jQuery function
$.fn.val = function (value) {
// if getter, just return original
if (!arguments.length) {
return $val.call(this);
}
// get result of original function
var result = $val.call(this, value);
// trigger angular input (this[0] is the DOM object)
ng.element(this[0]).triggerHandler('input');
// return the original result
return result;
}
})(window.jQuery, window.angular);
このスクリプトをjQueryとangular.jsの後にポップするだけで、val(value)
更新がうまくいくはずです。
縮小版:
!function(n,t){"use strict";var r=n.fn.val;n.fn.val=function(n){if(!arguments.length)return r.call(this);var e=r.call(this,n);return t.element(this[0]).triggerHandler("input"),e}}(window.jQuery,window.angular);
例:
この回答は、私の回答から別の同様の質問への逐語的コピーです。
ただ使用する:
$('#selectedDueDate').val(dateText).trigger('input');
の代わりに:
$('#selectedDueDate').val(dateText);