1

これは、タグを編集可能なテキスト フィールドに置き換える AngularJS ウィジェットです。テキストをクリックすると入力フィールドに置き換えられ、入力で Enter キーを押すと既存のリソースが更新されます。

作成したコードに満足していません。これらすべての evals と apply は本当に必要ですか? どうすればこれを改善できますか?

使用するには

editable-text(model="activeCustomer.phone_number", resource="Customer", field="phone_number")

指令コード

.directive("editableText", function($injector){
  return {
    restrict: "E",
    templateUrl: document.views.directivePartials.editableText,
    link: function(scope, elem, attrs){
      $(elem).find(".noEdit").click(function(){
        scope.showEdit = true;
        scope.$apply();
      });

      var ENTER = 13;
      $(elem).find('.edit').keyup(function(event){
        if(event.keyCode == ENTER){
          var resource = $injector.get(attrs.resource);

          var params = {};
          params[attrs.field] = scope.value
          resource.update(params);
          scope.showEdit=false;
        }
      });

      scope.showEdit = false;
      scope.$watch(attrs.model, function(){
        scope.value = scope.$eval(attrs.model);
      });
    },
  };
})

テンプレート

span.editableTextField
input.edit(type="text", ng-show="showEdit", ng-model="value")
span.noEdit(ng-show="!showEdit") {{value}}
4

3 に答える 3

2

特に学習中の場合は、Angular で jQuery を使用しないことをお勧めします。あなたがしていることのどれもそれを必要としません。

  1. テンプレートで使用することにより、clickコールバックの最初の使用を取り除くことができます。ngClick

    <span class="editableTextField" ng-click="showEdit = true">
    
  2. keyupAngular-UI を使用して、コールバック購入を取り除くことができます。

    <input class="edit" ... ui-keypress="{enter: 'handleEnter()'}">
    
  3. データをスコープに適切に書き戻すことができるように、双方向バインディングを使用することをお勧めします。

  4. を接続する$watchと、新しい値が最初の引数として取得されます。それはあなたに別の節約になります$eval

ここにフィドルがあります... http://jsfiddle.net/maU9t/

于 2013-05-07T19:39:01.510 に答える
0

フィドル!http://jsfiddle.net/pvtpenguin/25cqs/17

変更点:

  1. ディレクティブがテンプレートで使用するon-enterディレクティブを作成します。editable-text新しいon-enterディレクティブはどこでも再利用できます。

    <input ... on-enter="update()" ... /> 
    
  2. jquery と関数に依存する代わりに、ディレクティブを使用して状態ng-clickを切り替えます。showEdit

    <input ... on-click="showEdit = true" ... /> 
    
  3. valueディレクティブの分離スコープで、ディレクティブのモデル属性の値にバインドします。これにより、 を削除して、ローカルとscope.$watchの間の双方向バインディングを作成できます。valueactiveCustomer.phone_number

    <editable-text model="activeCustomer.phone_number"></editable-text>
    <input ... ng-model="value" />
    <span>{{value}}</span>
    
    ...
    
    scope: { 
        // give `value` and `activeCustomer.phone_number two-way binding
        value: '=model' 
    }
    

これらの変更により、jQuery の依存関係が完全に削除されます。結果のディレクティブ:

myApp.directive("editableText", function($injector){
  return {
    restrict: "E",
    scope: { 
        value: '=model' // Bind `value` to what is declared on the `model` attribute
    },
    templateUrl: "/tpl.html",
    link: function(scope, elem, attrs){
      scope.update = function() {
          var resource = $injector.get(attrs.resource);
          var params = {};
          params[attrs.field] = scope.value;
          resource.update(params);
          scope.showEdit=false;
      };
      scope.showEdit = false;
    }
  };
});
于 2013-05-07T21:17:12.430 に答える