2014-09-10 46 views
1

我是Stackoverflow的新手。我也是AngularJS的新手。如果我沒有正確使用,我很抱歉。不過,我正在嘗試使用AngularJS創建一個UI控件。我的UI控件將如下所示:在AngularJS中創建可重用組件

+---------------------+ 
|      | 
+---------------------+ 

是。一個文本框,它具有特殊功能。我打算把它放在帶按鈕的頁面上。我的想法是作爲一個開發者,我想給喜歡這類東西:

<ul class="list-inline" ng-controller="entryController"> 
    <li><my-text-box data="enteredData" /></li> 
    <li><button class="btn btn-info" ng-click="enterClick();">Enter</button></li> 
</ul> 

請注意,我不希望在我的控制按鍵。我還希望enteredData在與子控件關聯的範圍內可用。換句話說,當調用enterClick時,我希望能夠通過$scope.enteredData讀取值。在嘗試創建my-text-box,我已經建立了以下指令:

myApp.directive('myTextBox', [function() { 
    return { 
     restrict:'E', 
     scope: { 
      entered: '=' 
     }, 
     templateUrl: '/templates/myTextBox.html' 
    }; 
}]); 

myApp.controller('myTextBoxController', ['$scope', function($scope) { 
    $scope.doSomething = function($item) { 
     $scope.entered = $item.name; 

     // Need to somehow call to parent scope here. 
    }; 
}]); 

myTextBox.html

<div ng-controller="myTextBoxController"> 
    <input type="text" class="form-control" ng-model="query" placeholder="Please enter..." /> 
</div> 

entryController.js

myApp.controller('entryController', ['$scope', function($scope) { 
    $scope.enteredData = ''; 
    $scope.enterClick = function() { 
    alert($scope.enteredData); 
    }; 
}); 

現在,我有兩個問題。

  1. entryControllerenterClick叫,$scope.enteredData是空的。
  2. doSomethingmyTextBoxController被調用時,我不知道如何與entryController通信發生了什麼。

我覺得我已經正確設置了我的指令。我不確定我做錯了什麼。有人可以請指出我正確的方向。

回答

1

三個建議給你。

1)你真的不應該使用引用其他地方定義的控制器的模板來創建指令。它使得指令不可能單獨進行測試,並且通常不清楚。如果您需要將數據從父範圍傳遞到一個指令中使用分離的範圍對象的指令綁定到數據(注意如何指令模板沒有控制器)http://jsfiddle.net/p4ztunko/

myApp.directive('myTextBox', [function() { 
    return { 
     restrict: 'E', 
     scope: { 
      data: '=' 
     }, 
     template: '<input type="text" class="form-control" ng-model="data" placeholder="Please enter..." />' 
    }; 
}]); 

myApp.controller('entryController', ['$scope', function ($scope) { 
    $scope.enteredData = 'Stuff'; 
    $scope.enterClick = function() { 
     alert($scope.enteredData); 
    }; 
}]); 

<div> 
    <ul class="list-inline" ng-controller="entryController"> 
     <li>{{enteredData}} 
      <my-text-box data="enteredData" /> 
     </li> 
     <li> 
      <button class="btn btn-info" ng-click="enterClick();">Enter</button> 
     </li> 
    </ul> 
</div> 

2)唐當你不需要的時候不會對HTML進行混淆。 angular的目標之一是使標記更具可讀性,而不是用隨機自定義元素替換標準元素。例如。如果你想觀看的輸入值,並採取不同的行動對什麼是你可以做的是,在鏈接功能(注:還沒有引用外部控制器)http://jsfiddle.net/Lkz8c5jo/

myApp.directive('myTextBox', function() { 
    return { 
     restrict: 'A', 
     link: function(scope, element, attrs){ 
      function doSomething (val) { 
       alert('you typed ' + val); 
      } 
      scope.$watch(attrs.ngModel, function (val) { 
       if(val == 'hello'){ 
        doSomething(val); 
       } 
      }); 
     } 
    }; 
}); 

myApp.controller('entryController', ['$scope', function ($scope) { 
    $scope.enteredData = 'Stuff'; 
    $scope.enterClick = function (data) { 
     alert('You clicked ' + data); 
    }; 
}]); 

<div> 
    <ul class="list-inline" ng-controller="entryController"> 
     <li>{{enteredData}} 
      <input type="text" ng-model="enteredData" my-text-box /> 
     </li> 
     <li> 
      <button class="btn btn-info" ng-click="enterClick(enteredData)">Enter</button> 
     </li> 
    </ul> 
</div> 

3)將數據傳遞到控制器函數,而不是像ng-click =「enterClick(enteredData)」那樣引用函數中的$ scope對象。它使得測試更容易,因爲您從該方法中刪除了$ scope依賴關係

0

$ scope.enteredData爲空,因爲您沒有使用正確的範圍。 entryController中的$ scope與myTextBoxController中的$ scope不同。您需要在指令中指定這些控制器中的一個,然後使用它來引用適當的範圍。

看起來你應該將enterClick和相應的按鈕移動到你的指令模板中。然後將輸入點擊移動到您的文本框控制器,您將能夠引用$ scope.enteredData。

您可以使用$ emit通知更改的父範圍。 (這是參考你的評論「//需要以某種方式調用父範圍在這裏。」)

此外,您可能有一個問題沒有使用適當的變量。在myTextBox指令中,聲明瞭$ scope.entered,但是您有效地將$ scope.data設置爲等於html中enteredData的值。