Angular JS和复杂指令

时间:2013-05-07 17:24:47

标签: javascript angularjs angularjs-directive

这是一个AngularJS小部件,用可编辑的文本字段替换标记。单击该文本将其替换为输入字段,并在输入上按Enter键更新现有资源。

我对我制作的代码不满意。所有这些遗嘱和申请是否真的有必要?我怎样才能改善这个?

使用

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}}

3 个答案:

答案 0 :(得分:2)

我建议不要在Angular中使用jQuery,特别是当你正在学习时。你所做的一切都不需要它。

  1. 您可以在模板中使用click摆脱首次使用ngClick回调:

    <span class="editableTextField" ng-click="showEdit = true">
    
  2. 您可以使用Angular-UI摆脱keyup回调购买:

    <input class="edit" ... ui-keypress="{enter: 'handleEnter()'}">
    
  3. 我建议使用双向绑定,以便您可以正确地将数据写回范围。

  4. 当您连接$watch时,您将获得新值作为第一个参数。这将为您节省另一个$eval

  5. 这是你的小提琴...... http://jsfiddle.net/maU9t/

答案 1 :(得分:0)

小提琴! http://jsfiddle.net/pvtpenguin/25cqs/17

的变化:

  1. 创建on-enter指令,editable-text指令在模板中使用。新的on-enter指令可以在任何地方重复使用。

    <input ... on-enter="update()" ... /> 
    
  2. 使用ng-click指令切换showEdit状态,而不是依赖于jquery和函数。

    <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' 
    }
    
  4. 这些更改完全删除了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;
        }
      };
    });
    

答案 2 :(得分:0)

这是内联编辑器的一个版本。 http://jsfiddle.net/pUMer/

主要特点:

  • 配置内联编辑器的初始模式
  • 每个内联编辑器的单独范围,以便它不会干扰 父范围
  • 查看所有内联编辑器的模型

如果您只想要内联编辑器,请参阅。将数组元素减小到一个大小。

<强> HTML

<inline-editor inline-editor-mdl="inlineEditor"></inline-editor>