0

私はこのフィドルを持っていて、これを機能させることはできません。その理由は、カスタムディレクティブのインプレース編集共有スコープを持つ2つのli要素にあると思います。解決策は、親にバインドするスコープのコピーを作成するようにディレクティブに指示することです-ヘルプをトランスクルージョンできますか?

angular.module('bla', [])
    .directive('editInPlace', ['$parse','$compile', function($parse, $compile) {
    return {
        restrict: 'A',
        scope: true,
        link: function (scope, element, attribs) {
            var inputStart = '<input style="border: 2 solid black" name="inPlaceInput" style="display:none" value="';
            var inputEnd = '">';

            scope.editModeAccessor = $parse(attribs.editInPlace);
            scope.modelAccessor = $parse(attribs.ngBind);

            scope.$watch(attribs.editInPlace, function(newValue, oldValue){
                if (newValue){
                    console.debug("click");
                    console.debug("value: " + scope.modelAccessor(scope));
                    var inputHtml = inputStart + scope.modelAccessor(scope) + inputEnd;
                    element.after(inputHtml);
                    jQuery(element).hide();
                    scope.inputElement = jQuery("input[name=inPlaceInput]");
                    scope.inputElement.show();
                    scope.inputElement.focus();
                    scope.inputElement.bind("blur", function() {
                        blur();
                    });
                } else {
                    blur();
                }
            });

            function blur(){
                console.debug("blur secondary");
                if (scope.inputElement){
                    console.debug("blur secondary inputElement found");
                    var value = scope.inputElement.val();
                    console.debug("input value: "+ value);
                    scope.inputElement.remove();
                    jQuery(element).show();
                    scope.editModeAccessor.assign(scope, false);
                    scope.modelAccessor.assign(scope, value);
                }
            }
        }
    }
                            }]);

function ContactsCtrl($scope, $timeout){
    $scope.contacts = [{number:'+25480989333', name:'sharon'},{number:'+42079872232', name:''}];
    $scope.editMode = false;
    var editedId;
    $scope.edit = function(id){
        $scope.editMode = true;
        jQuery("#"+id).hide();
        editedId = id;
        //TODO show delete button
    }
    $scope.$watch('editMode', function(newValue, oldValue){
        if (!newValue && editedId){
            jQuery("#"+editedId).show();
        }
    });
}


<div ng-app="bla">
<div ng-controller="ContactsCtrl">
<h4>Contacts</h4>
<ul>
    <li ng-repeat="contact in contacts">
        <span edit-in-place="editMode" ng-bind="contact.number"></span>
        <span edit-in-place="editMode" ng-bind="contact.name"></span>
        <span id="{{$index}}" ng-click="edit($index)"><i class="icon-edit">CLICKtoEDIT</i></span>
    </li>
</ul>
</div></div>
4

1 に答える 1

2

スコープのクローンを作成するのは最善の解決策ではないと思います。

角度でディレクティブを作成するときは、ディレクティブ内のすべての機能をカプセル化する必要があります。また、必要がない場合は、jQueryを混在させないようにする必要があります。ほとんどの場合(この場合のように)、不必要な複雑さを導入しているだけです。style最後に、クラスは、要素の属性ではなく、表示を制御するための最良の方法です。

私は、jQueryを使用せずに、より「角度のある」方法でディレクティブを自由に書き直すことができました。更新されたjsFiddleからわかるように、よりシンプルでクリーンです。また、それは動作します!

このディレクティブは簡単に変更して、多くのすばらしい機能を追加できます。

app.directive( 'editInPlace', function() {
  return {
    restrict: 'E',
    scope: { value: '=' },
    template: '<span ng-click="edit()" ng-bind="value"></span><input ng-model="value"></input>',
    link: function ( $scope, element, attrs ) {
      // Let's get a reference to the input element, as we'll want to reference it.
      var inputElement = angular.element( element.children()[1] );

      // This directive should have a set class so we can style it.
      element.addClass( 'edit-in-place' );

      // Initially, we're not editing.
      $scope.editing = false;

      // ng-click handler to activate edit-in-place
      $scope.edit = function () {
        $scope.editing = true;

        // We control display through a class on the directive itself. See the CSS.
        element.addClass( 'active' );

        // And we must focus the element. 
        // `angular.element()` provides a chainable array, like jQuery so to access a native DOM function, 
        // we have to reference the first element in the array.
        inputElement[0].focus();
      };

      // When we leave the input, we're done editing.
      inputElement.prop( 'onblur', function() {
        $scope.editing = false;
        element.removeClass( 'active' );
      });
   }
};

});

于 2013-01-05T08:00:02.453 に答える