angular.js - angularjs scope.$watch取不到input变化的值
仅有的幸福
仅有的幸福 2017-05-15 16:49:37
0
5
837

我想用angularjs和my97datepicker做一个东西,写了一个direcitve,在点击选择完时间之后,把值同步到scope上面。描述的有点乱,看下主要代码:

javascriptvar datepicker=angular.module("datepicker",[]);
datepicker.controller("datepickerCtrl",function($scope){
    $scope.date="2014-10-14";
});
datepicker.directive("datePicker",function(){
    return {
        restrict:"A",
        link:function(scope,element,attr){
            element.bind("click",function(){
                window.WdatePicker();
            });
            //问题在这里,无法取到变化的值,而且加上这个,连初始的值都无法显示出来。
            scope.$watch(attr.value,function(newVal){
                scope.date=newVal;
            });
        }
    };
});

在线地址:http://jsfiddle.sinaapp.com/4zz6nvadg/embedded。初学angularjs,每次写directive都是卡在$watch这里。

仅有的幸福
仅有的幸福

全員に返信(5)
洪涛

あなたが使ったプラグインを使ったことがなく、今は勉強する時間がないので、解決方法がわかりません。しかし、問題がどこにあるのかは私が教えますので、あなたは自分で解決策を見つけることができます。まずはスクリーンショットを見てください:

  1. プラグインが正しく実行されることを確認するために、最初に $watch 関連のコードをコメント アウトします。
  2. $watch 相关的代码,以确保插件正确执行
  3. 注意下面:2014-10-14 出现在 DOM 的哪里了吗?
  4. $watch 部分你监视的是 attr.value,然而根据截图可以发现插件设定的日期根本就不是保存在 input[value] 这里,无论如何 input[value] 都是空值
  5. 因此,$watch 所做的仅仅是读取一个不存在的值,并且覆盖了 model,这就是为什么加上 $watch 部分之后,连 model 都失效的缘故。

知道原因之后,解决办法就简单了,要么让插件把你想要的值写到 input[value] 去,要么反过来,找到正确的地方去取值去 $watch,具体办法自己去查询插件的文档或源码吧。


吃了晚饭,帮你看一下插件的源代码,实际上人家提供了几个事件回调函数,而且你不必非用 $watch 的,代码如下:

var datepicker=angular.module("datepicker",[]);
datepicker.controller("datepickerCtrl",function($scope){
  $scope.date="2014-10-14";
});
datepicker.directive("datePicker",function(){
  return {
    restrict:"A",
    link:function(scope, element, attr){
      element.bind("click", function () {
        window.WdatePicker({
          onpicked: function () {
            scope.$apply(scope.date = this.value);
          }
        });
      });
    }
  };
});

Demo: http://jsfiddle.sinaapp.com/4zz6n9usy

想用 $watch 也可以,这样写:

var datepicker=angular.module("datepicker",[]);
datepicker.controller("datepickerCtrl",function($scope){
  $scope.date="2014-10-14";
});
datepicker.directive("datePicker",function(){
  return {
    restrict:"A",
    link:function(scope, element, attr){
      element.bind("click", function () {
        window.WdatePicker({
          onpicked: function () { scope.$digest(); }
        });
      });
      scope.$watch(
        function () { return element[0].value },
        function (newValue) { scope.date = newValue; }
      );
    }
  };
});

Demo: http://jsfiddle.sinaapp.com/4zz6n9t9q

注意,这里第一个参数不能是直接 element[0].value,因为这个值是一个 primitive string,而不是 angular 封装过的对象,所以要用一个 getter 函数显式的去获取,否则你拿不到的。

而且这里还必须得依赖插件的回调函数做一下 scope.$digest(),否则 scope.date次の点に注意してください: 2014-10-14 は DOM のどこに表示されますか?

$watch セクションで監視しているのは attr.value ですが、スクリーンショットによると、プラグによって設定された日付であることがわかります。 -in は input[value] にまったく保存されません。ここでは、input[value] は何があっても空です。 #🎜🎜#つまり、$watch が行うことは、存在しない値を読み取り、model を上書きすることだけです。そのため、$watch が の後に追加されます。 > 部分では、model も無効です。 #🎜🎜#理由がわかれば、解決策は簡単です。input[value] に必要な値をプラグインに書き込むか、その逆に値を取得する適切な場所を見つけます。 $watch については、プラグインのドキュメントまたはソース コードで特定のメソッドを確認してください。 #🎜🎜# #🎜🎜# 夕食後、プラグインのソース コードを見てみましょう。実際、プラグインにはいくつかのイベント コールバック関数が用意されており、$watch を使用する必要はありません。コードは次のとおりです: #🎜🎜 # リーリー #🎜🎜#デモ: http://jsfiddle.sinaapp.com/4zz6n9usy#🎜🎜# #🎜🎜# $watch を使用したい場合は、次のように記述できます: #🎜🎜# リーリー #🎜🎜#デモ: http://jsfiddle.sinaapp.com/4zz6n9t9q#🎜🎜# #🎜🎜#この値はプリミティブ文字列であり、Angular でカプセル化されたオブジェクトではないため、最初のパラメーターを直接 element[0].value にすることはできないことに注意してください。そのため、ゲッター関数 Get を使用する必要があります。明示的に指定しないと取得できません。 #🎜🎜# #🎜🎜#ここでは、プラグインのコールバック関数に依存して scope.$digest() を実行する必要があります。そうしないと、scope.date は自動的に更新されません。最初の例の方が単純で、パフォーマンスが優れていることがわかります。 #🎜🎜#
いいねを押す +0
PHPzhong

なぜこのように使用されるのかわかりません。ここで、プロパティとスコープは異なるという概念を明確にする必要があります。プロパティの値をスコープにバインドする場合は、スコープを宣言する必要があります。ディレクティブには 3 つの方法があります:

  • =双方向属性
  • @attrワン・ダイレクション
  • &attr関数

あなたの考えによれば、次のような方法かもしれません:

リーリー

ただし、バインドが行われたとしても、この要素の値の変更はデフォルトでは Angular によって監視されないことを理解する必要があります 这个绑定只是说要去绑定这个属性值对应的变量 もちろん、値の変更を監視することはできません。
実際には、ng-model と ng-change を使用するだけで十分です。

次のようになるかもしれません:

リーリー
いいねを押す +0
黄舟

$scope を渡してみてください! $watch は $scope

に基づいています
いいねを押す +0
習慣沉默

linkの詳細なドキュメントが見つからず、attrの使い方もよく分かりませんが、要素の値を$watchingしてみると良いと思います。

上記の 2 人の場合、ディレクティブ内のスコープはその $scope であり、attr はリンク内のパラメータであり、個別に定義する必要はありません。

いいねを押す +0
某草草

こんにちは、大家さん、最終的にこの問題を解決するにはどうすればよいですか? ng-model から得た値はまだ未定義ですか?

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!