2014-07-17 109 views
0

假設我有這樣的事情:如何創建委託給ngModel的自定義AngularJS指令?

<div my-custom-root="root"> 
    <input type="text" my-custom-Path="path.to.somewhere" /> 
</div> 

現在我想這個翻譯的東西,其行爲基本上equivilant到:

<input type="text" ng-model="root.path.to.somewhere" /> 

我弄到指定的兩項指令,得到所有的對象等。這些爲我提供根對象和路徑,但是如何從那些創建綁定?我錯過了適當的ng-model指令的生成或直接使用NgModelController

我創建了一個plunkr here與我設法到目前爲止的東西。

因爲在這裏更容易引用我的指令代碼,就像他們可以在我的plunkr發現還有:

app.directive('myCustomRoot', function() { 
    var container; 

    return { 
     controller: function($scope) { 
      this.container = function() { 
       return container; 
      }; 
     }, 

     compile: function() { 
      return function ($scope, elm, attrs) { 
       $scope.$watch(attrs.myCustomRoot, function(newVal) { 
        container = newVal; 
       }); 
      }; 
     } 
    }; 
}); 

app.directive('myCustomPath', function($parse) { 
    return { 
     require: '^myCustomRoot', 

     link: function(scope, element, attrs, containerController) { 
      var getter = $parse(attrs.myCustomPath); 
      scope.$watch(function() { 
        return containerController.container(); 
       }, 
       function(newVal) { 
        if (newVal) { 
         alert('The value to be edited is: ' + getter(newVal) + '\nIt is the property "' + attrs.myCustomPath + '"\non Object: ' + JSON.stringify(newVal) + '\n\nNow how do I bind this value to the input box just like ng-model?'); 
        } 
       } 
      ); 
     } 
    }; 
}); 

你可以看到,我把所有可用的東西在我的警報盒,但我不知道如何做綁定。

+0

有一個與你已經使用過的吸氣劑非常相似的接觸器方法... – harishr

+0

@HarishR:你的意思是我的財產的二傳手?是的,我可以使用它來更新值,但是我每次需要更改''元素時都要這樣做。是的,我可以在輸入中註冊監聽器,但是這樣做,但是ng-model指令可以完成所有這些。所以我希望我能以某種方式利用它。 – yankee

+0

對我來說似乎過於複雜,你只需要'my-custom-root'的字符串值,這樣你就可以設置'ng-model'屬性並編譯它 – charlietfl

回答

0

我希望有一些方法可以編寫someBindingService.bindInput(myInput, myGetter, mySetter),但是我做了很多源代碼閱讀,不幸的是綁定與編譯密切相關。

但是由於這個問題:「Add directives from directive in AngularJS」我設法想出一個辦法,這是不太優雅,但它是緊湊和有效的:

app.directive('myCustomPath', function($compile, $parse) { 
     return { 
     priority: 1000, 
     terminal: true, 

     link: function(scope, element, attrs, containerController) { 
      var containerPath = element.closest('[my-custom-root]').attr('my-custom-root'); 
      attrs.$set('ngModel', containerPath + '.' + attrs['myCustomPath']); 
      element.removeAttr('my-custom-path'); 
      $compile(element)(scope); 
     } 
     } 
    }); 

這使用jQuery的一點點,但它不應該是也很難用普通的jQLite來完成。

+0

您可能需要'^ myCustomRoot'並在控制器中設置/獲取其屬性,這將消除jQuery的使用。 – runTarm

+0

@runTarm:不,我不能。控制器在鏈接時不可用(如果我誤解了你的話,請參考示例) – yankee

+0

請參閱http://plnkr.co/edit/QFDmIXhzaF2plKw2hYpw?p=preview中的「my-custom-path2」指令 – runTarm