Angular JS and Complex Directives

二次信任 提交于 2019-12-06 14:22:33

问题


This is an AngularJS widget which replaces a tag with an editable text field. Clicking the text replaces it with an input field, and hitting enter on the input updates an existing resource.

I am not happy with the code I produced. Are all of these evals and applys really necessary? How can I improve this?

To use

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

The Directive Code

.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);
      });
    },
  };
})

The Template

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

回答1:


I would recommend not using jQuery with Angular, especially as you're learning. None of what you're doing requires it.

  1. You can get rid of the first use of click callback by using ngClick in your template:

    <span class="editableTextField" ng-click="showEdit = true">
    
  2. You can get rid of the keyup callback buy using Angular-UI:

    <input class="edit" ... ui-keypress="{enter: 'handleEnter()'}">
    
  3. I'd recommend using a two-way binding so you can write data back to the scope properly.

  4. When you wire up $watch, you get the new value as the first argument. That will save you another $eval.

Here's a fiddle for you... http://jsfiddle.net/maU9t/




回答2:


Fiddle! http://jsfiddle.net/pvtpenguin/25cqs/17

Changes:

  1. Create an on-enter directive that the editable-text directive uses in the template. The new on-enter directive can be reused anywhere.

    <input ... on-enter="update()" ... /> 
    
  2. Use the ng-click directive to toggle showEdit state instead of relying on jquery and a function.

    <input ... on-click="showEdit = true" ... /> 
    
  3. Binds value on the directive's isolate scope to the value of the directive's model attribute. This lets us remove the scope.$watch and creates a two-way binding between the local value and activeCustomer.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' 
    }
    

These changes completely remove the jQuery dependency. Resulting directive:

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



回答3:


Here is one version of inline editor. http://jsfiddle.net/pUMer/

Key features:

  • Configure the initial mode of the inline editor
  • Seperate scope for each inline editor, so that it wont interfere with the parent scope
  • View the model of all the inline editors

If you want only on inline editor, pls. reduce the array element to size of one.

HTML:

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


来源:https://stackoverflow.com/questions/16425012/angular-js-and-complex-directives

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!