AngularJs 指令隔离作用域
AngularJs directives isolate scope
我有一个使用自定义指令的简单应用程序,但我在尝试使用隔离范围时完全迷失了,请看看并告诉我要写什么以填补空白。
应用的创意是什么!
a) 应用程序控制器使用 $http 从服务生成 menu_list 项,然后使用 found 函数进行搜索并 return foundItems 数组(这一切都完成了!)。
b) 该指令有一个有序列表循环抛出找到的项目并显示它们加上每个项目旁边的按钮以在需要时将其删除(这仍然需要)。
我错过了什么:
我的 directive.html 中有三个地方我评论说 <-- <== 这里要说什么 <== <== -->
我也在 index.html 中评论过 <-- 不确定 -->
以及我的 app.js 评论 <-- 不确定 -->
请看看这 5 个地方,告诉我该怎么做!
index.html :
<!doctype html>
<html lang="en" ng-app="NarrowItDownApp">
<head>
<title>Narrow Down Your Menu Choice</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles/bootstrap.min.css">
<link rel="stylesheet" href="styles/styles.css">
</head>
<body>
<div class="container" ng-controller="NarrowItDownController">
<h1>Narrow Down Your Chinese Menu Choice</h1>
<div class="form-group">
<input type="text" placeholder="search term" class="form-control" ng-model="searchTerm">
</div>
<div class="form-group narrow-button">
<button class="btn btn-primary" ng-click="found(searchTerm)">Narrow It Down For Me!</button>
</div>
<found-items items="found(searchTerm)"></found-items>
<!-- Not sure -->
</div>
<script src="scripts/angular.min.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
directive.html:
<div>
<ol>
<li ng-repeat="item in items"><!-- <== What to say here <== <== -->
{{ item.name }}, {{ item.shortName }}, {{item.description}}
<button ng-click="remove">Remove item</button> <!-- <== What to say here <== <== -->
</li>
</ol>
<div class="error" ng-if="foundItem.length">nothing found
</div> <!-- <== What to say here <== <== -->
</div>
app.js:
var app = angular.module('NarrowItDownApp', []);
app.controller('NarrowItDownController', ['$scope', 'MenuSearchService', function($scope, MenuSearchService) {
var $scope = $scope;
$scope.searchTerm = 'soup';
$scope.found = function() {
return MenuSearchService.getMatchedMenuItems($scope.searchTerm);
}
console.log(MenuSearchService.getMatchedMenuItems($scope.searchTerm));
$scope.remove = function(index){
service.removeItem(index);
}
}]);
app.service('MenuSearchService', ['$http', function($http) {
var service = this;
service.getMatchedMenuItems = function(searchTerm) {
searchTerm = searchTerm.toLowerCase();
return $http({
method: 'GET',
url: 'https://davids-restaurant.herokuapp.com/menu_items.json'
})
.then(function(response) {
var result = response.data.menu_items;
console.log('Result: ' + result.length);
var foundItems = [];
result.forEach(function(obj) {
if (searchTerm != '') {
if ((obj.name.indexOf(searchTerm) != -1) || (obj.description.indexOf(searchTerm) != -1)) {
foundItems.push(obj);
}
}
})
console.log('Found Items: ' + foundItems.length)
return foundItems;
}, function(error) {
console.log('Error from $http' + error);
});
}
service.removeItem = function(index){
service.getMatchedMenuItems(index).splice(index, 1);
}
}]);
app.directive('foundItems', function() {
var ddo = {
templateUrl: 'directive.html',
scope: {
items: '<found' // Not sure
}
}
return ddo;
});
注意:我稍后会编写 remove 方法并更新问题,但目前这不是必需的。
先感谢您!
更新:对服务和控制器上的删除方法进行了编码。
查看文档 here。您需要定义指令将使用的绑定类型。如果将对象传递给指令,它将是 =
。所以指令范围定义将是这样的:
scope: {
items: '='
}
在那之后,您的指令范围将只定义 items
而不是所有其他父范围对象。您可以像往常一样使用该变量:
ng-repeat="item in items"
对于像 remove 这样的事情,你可以在你的指令中实现功能,但它要做的超出了你当前问题的范围。也许调用 $http?
您似乎在指令和组件之间来回切换。组件具有您引用的单向绑定 <
。您的指令应如下所示:
app.directive('foundItems', function() {
var ddo = {
restrict: 'E', //Since this is a directive and not a component, you need to define which type (E = Element since you're using <found-items>)
templateUrl: 'directive.html',
scope: {
items: '=' // This is two-way binding which you'll need for the array
},
controller: function ($scope) {
$scope.remove = function (item) {
// This can be where you make a call to your service to remove the item on the server
var index = $scope.items.indexOf(item);
if(index >= 0) {
$scope.items.splice(index, 1);
}
}
}
}
return ddo;
});
然后在您的控制器中,我建议您将搜索功能和结果分开:
app.controller('NarrowItDownController', ['$scope', 'MenuSearchService', function($scope, MenuSearchService) {
$scope.searchTerm = 'soup';
// It looks like you want to use found as both the results and the search function. Separate them.
$scope.search = function(searchTerm) {
console.log('Searching for ' + searchTerm);
MenuSearchService.getMatchedMenuItems(searchTerm).then(function(foundItems) {
// The service executes asynchronously so use the then() to create a callback and store the results.
$scope.results = foundItems;
});
};
$scope.search($scope.searchTerm);
}]);
标记如下 - 注意 ng-repeat
。您将它分配给一个变量并在元素内部使用该变量。然后 ng-if
是你的条件,当 div 应该显示你有 0 个结果时。
<div>
<ol>
<li ng-repeat="item in items">
{{ item.name }}, {{ item.shortName }}, {{item.description}}
<button ng-click="remove(item)">Remove item</button>
</li>
</ol>
<div class="error" ng-if="items.length == 0">nothing found </div>
</div>
我有一个使用自定义指令的简单应用程序,但我在尝试使用隔离范围时完全迷失了,请看看并告诉我要写什么以填补空白。
应用的创意是什么!
a) 应用程序控制器使用 $http 从服务生成 menu_list 项,然后使用 found 函数进行搜索并 return foundItems 数组(这一切都完成了!)。
b) 该指令有一个有序列表循环抛出找到的项目并显示它们加上每个项目旁边的按钮以在需要时将其删除(这仍然需要)。
我错过了什么:
我的 directive.html 中有三个地方我评论说 <-- <== 这里要说什么 <== <== -->
我也在 index.html 中评论过 <-- 不确定 --> 以及我的 app.js 评论 <-- 不确定 -->
请看看这 5 个地方,告诉我该怎么做!
index.html :
<!doctype html>
<html lang="en" ng-app="NarrowItDownApp">
<head>
<title>Narrow Down Your Menu Choice</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles/bootstrap.min.css">
<link rel="stylesheet" href="styles/styles.css">
</head>
<body>
<div class="container" ng-controller="NarrowItDownController">
<h1>Narrow Down Your Chinese Menu Choice</h1>
<div class="form-group">
<input type="text" placeholder="search term" class="form-control" ng-model="searchTerm">
</div>
<div class="form-group narrow-button">
<button class="btn btn-primary" ng-click="found(searchTerm)">Narrow It Down For Me!</button>
</div>
<found-items items="found(searchTerm)"></found-items>
<!-- Not sure -->
</div>
<script src="scripts/angular.min.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
directive.html:
<div>
<ol>
<li ng-repeat="item in items"><!-- <== What to say here <== <== -->
{{ item.name }}, {{ item.shortName }}, {{item.description}}
<button ng-click="remove">Remove item</button> <!-- <== What to say here <== <== -->
</li>
</ol>
<div class="error" ng-if="foundItem.length">nothing found
</div> <!-- <== What to say here <== <== -->
</div>
app.js:
var app = angular.module('NarrowItDownApp', []);
app.controller('NarrowItDownController', ['$scope', 'MenuSearchService', function($scope, MenuSearchService) {
var $scope = $scope;
$scope.searchTerm = 'soup';
$scope.found = function() {
return MenuSearchService.getMatchedMenuItems($scope.searchTerm);
}
console.log(MenuSearchService.getMatchedMenuItems($scope.searchTerm));
$scope.remove = function(index){
service.removeItem(index);
}
}]);
app.service('MenuSearchService', ['$http', function($http) {
var service = this;
service.getMatchedMenuItems = function(searchTerm) {
searchTerm = searchTerm.toLowerCase();
return $http({
method: 'GET',
url: 'https://davids-restaurant.herokuapp.com/menu_items.json'
})
.then(function(response) {
var result = response.data.menu_items;
console.log('Result: ' + result.length);
var foundItems = [];
result.forEach(function(obj) {
if (searchTerm != '') {
if ((obj.name.indexOf(searchTerm) != -1) || (obj.description.indexOf(searchTerm) != -1)) {
foundItems.push(obj);
}
}
})
console.log('Found Items: ' + foundItems.length)
return foundItems;
}, function(error) {
console.log('Error from $http' + error);
});
}
service.removeItem = function(index){
service.getMatchedMenuItems(index).splice(index, 1);
}
}]);
app.directive('foundItems', function() {
var ddo = {
templateUrl: 'directive.html',
scope: {
items: '<found' // Not sure
}
}
return ddo;
});
注意:我稍后会编写 remove 方法并更新问题,但目前这不是必需的。 先感谢您! 更新:对服务和控制器上的删除方法进行了编码。
查看文档 here。您需要定义指令将使用的绑定类型。如果将对象传递给指令,它将是 =
。所以指令范围定义将是这样的:
scope: {
items: '='
}
在那之后,您的指令范围将只定义 items
而不是所有其他父范围对象。您可以像往常一样使用该变量:
ng-repeat="item in items"
对于像 remove 这样的事情,你可以在你的指令中实现功能,但它要做的超出了你当前问题的范围。也许调用 $http?
您似乎在指令和组件之间来回切换。组件具有您引用的单向绑定 <
。您的指令应如下所示:
app.directive('foundItems', function() {
var ddo = {
restrict: 'E', //Since this is a directive and not a component, you need to define which type (E = Element since you're using <found-items>)
templateUrl: 'directive.html',
scope: {
items: '=' // This is two-way binding which you'll need for the array
},
controller: function ($scope) {
$scope.remove = function (item) {
// This can be where you make a call to your service to remove the item on the server
var index = $scope.items.indexOf(item);
if(index >= 0) {
$scope.items.splice(index, 1);
}
}
}
}
return ddo;
});
然后在您的控制器中,我建议您将搜索功能和结果分开:
app.controller('NarrowItDownController', ['$scope', 'MenuSearchService', function($scope, MenuSearchService) {
$scope.searchTerm = 'soup';
// It looks like you want to use found as both the results and the search function. Separate them.
$scope.search = function(searchTerm) {
console.log('Searching for ' + searchTerm);
MenuSearchService.getMatchedMenuItems(searchTerm).then(function(foundItems) {
// The service executes asynchronously so use the then() to create a callback and store the results.
$scope.results = foundItems;
});
};
$scope.search($scope.searchTerm);
}]);
标记如下 - 注意 ng-repeat
。您将它分配给一个变量并在元素内部使用该变量。然后 ng-if
是你的条件,当 div 应该显示你有 0 个结果时。
<div>
<ol>
<li ng-repeat="item in items">
{{ item.name }}, {{ item.shortName }}, {{item.description}}
<button ng-click="remove(item)">Remove item</button>
</li>
</ol>
<div class="error" ng-if="items.length == 0">nothing found </div>
</div>