[英]Filtering directive in Angular.js
我正在嘗試開發一個單獨的Web應用程序,即博客,顯示帖子。 ng-repeat
指令將它們包含在模板中:
<div class="post" data-ng-repeat="post in postList ">
<div class="date">published: {{post.published_at | date:'dd-MM-yyyy, HH:mm'}}</div>
<a class="btn btn-default" data-ng-click="editPost(post)"><span class="glyphicon glyphicon-pencil"></span></a>
<a class="btn btn-default" data-ng-click="deletePost(post)"><span class="glyphicon glyphicon-remove"></span></a>
<h1><a href="">{{post.title}}</a></h1>
<p>{{post.text}}</p>
</div>
</div>
它們具有在控制器中定義的字段,例如標題,文本和發布日期。 我想按各種標准過濾它們。 為此,我嘗試實現自己的自定義過濾器(以便可以按多個字段進行過濾):
angular.module("blog").
filter('bytitle', function() {
return function(posts, title) {
var out = [];
// Filter logic here, adding matches to the out var.
var i;
for(i = 0; i < posts.length; i++){
if(posts[i].title.indexOf(title) >=0){
out.push(posts[i]);
}
}
return out;
}
});
但是,如果我運行javascript控制台,則會出現以下錯誤,該錯誤僅由上述代碼的存在引起:
Argument 'postController' is not a function, got undefined
我是angular
新手,我不確定這意味着什么。 有任何想法嗎?
整個源代碼: http : //plnkr.co/edit/suATcx8dQXZqcmmwlc0b?p=catalogue
編輯2:問題已部分解決。 我添加了此過濾器功能:
<div class="post" data-ng-repeat="post in postList | bytitle : filterTerm">
但是運行腳本時出了點問題:
TypeError: Cannot read property 'length' of undefined
它發生在第7行(帶有posts.length
)。
編輯
在進行評論或編輯之前,我沒有從@grundy看到答案,因此應該接受它作為答案,但我想指出兩點:
我的首選方法是使用angular.isDefined / angular.isArray:
angular.module("blog").
filter('bytitle', function() {
return function(posts, title) {
if(angular.isDefined(title) && angular.isArray(posts)) {
var out = [];
// Filter logic here, adding matches to the out var.
var i;
for(i = 0; i < posts.length; i++){
if(posts[i].title.indexOf(title) >=0){
out.push(posts[i]);
}
}
return out;
} else {
return posts;
}
}
});
其次,我只想指出,雖然有時需要編寫自己的過濾器,並且一定要掌握一定的技巧,但對單個屬性進行過濾的最簡單方法是通過將內置屬性添加到模型值中來使用內置過濾器您要搜索的:
<input data-ng-model="filterTerm.title" />
<input data-ng-model="filterTerm.text" />
然后重復使用對象名稱添加過濾器,如下所示:
<div class="post" data-ng-repeat="post in postList | filter: filterTerm ">
然后,您可以將同一過濾器用於多個屬性。
在帶有過濾器的文件中,而不是angular.module("blog", [])
您需要angular.module("blog")
。
在第一種情況下-您在第二個模塊中創建-獲取。
見文檔 :
當傳遞兩個或多個參數時,將創建一個新模塊。 如果僅傳遞一個參數,則將檢索現有模塊(作為第一個參數傳遞給模塊的名稱)。
旁注:在插件中,您對js文件的引用有誤
您有length屬性錯誤,因為在通過ajax加載帖子之前,您沒有初始化此變量,因此在filter中傳遞了undefined 。
您可以像這樣修改過濾器
angular.module("blog").
filter('bytitle', function() {
return function(posts, title) {
var out = [];
//if not pass posts - return empty
if(!posts) return out;
//if not pass title, or it empty - return same collection
if(!title) return posts;
// Filter logic here, adding matches to the out var.
var i;
for (i = 0; i < posts.length; i++) {
if (posts[i].title.indexOf(title) >= 0) {
out.push(posts[i]);
}
}
return out;
}
});
var app = angular.module("blog", []); app.controller("postController", function($scope, $http, $timeout) { var path = 'http://private-79b25-blogtt.apiary-mock.com'; $scope.titleFilter = ""; $scope.contentFilter = ""; $http.get(path + '/posts') .success(function(data, status, headers, config) { $timeout(function() { $scope.postList = data; }); }) .error(function(data, status, headers, config) { console.log("error getting " + status); }); $scope.form_header = "New post"; $scope.addPost = function() { var post = { title: $scope.title, text: $scope.text, published_at: new Date() }; $http.post(path + '/posts', post) .success(function(data, status, headers, config) { $scope.postList.push(post); }) .error(function(data, status, headers, config) { console.log("error posting " + status); }); $scope.title = ""; $scope.text = ""; }; $scope.deletePost = function(post) { var del = confirm("Are you sure you want to delete or modify this post?"); if (del) { var i = $scope.postList.indexOf(post); $scope.postList.splice(i, 1); } }; var backupPostContent; $scope.editPost = function(post) { $scope.deletePost(post); $scope.form_header = "Edit post"; $scope.title = post.title; $scope.text = post.text; backupPostContent = post; }; $scope.cancelEdit = function() { $http.post(path + '/posts', backupPostContent) .success(function(data, status, headers, config) { $scope.postList.push(backupPostContent); $scope.form_header = "New post"; }) .error(function(data, status, headers, config) { console.log("error posting " + status); }); $scope.title = ""; $scope.text = ""; }; $scope.filter = function(term) { } }); angular.module("blog"). filter('bytitle', function() { return function(posts, title) { var out = []; if(!posts) return out; if(!title) return posts; // Filter logic here, adding matches to the out var. var i; for (i = 0; i < posts.length; i++) { if (posts[i].title.indexOf(title) >= 0) { out.push(posts[i]); } } return out; } });
#wrap { width: 600px; margin: 0 auto; } #left_col { float: left; width: 300px; } #right_col { float: right; width: 300px; } body { padding: 0px 15px; } .row-centered { text-align: right; } .page-header { background-color: #cb892c; margin-top: 0; padding: 20px 20px 20px 40px; } .page-header h1, .page-header h1 a, .page-header h1 a:visited, .page-header h1 a:active { color: #ffffff; font-size: 36pt; text-decoration: none; } .content { margin-left: 40px; } h1, h2, h3, h4 { font-family: Helvetica, sans-serif; } .date { float: right; color: #828282; } .save { float: right; } .post-form textarea, .post-form input { width: 60%; } .top-menu, .top-menu:hover, .top-menu:visited { color: #ffffff; float: right; font-size: 26pt; margin-right: 20px; } .post { margin-bottom: 70px; } .post h1 a, .post h1 a:visited { color: #000000; }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css" rel="stylesheet" /> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="blog" ng-controller="postController"> <div id="wrap"> <div id="left_col"> <h3> Search </h3> <p> <input data-ng-model="filterTerm" /> </p> </div> <div id="right_col"> <div id="wrap"> <div id="left_col"> <input type="checkbox" value="topic" id="title" ng-model="titleFilter" />In topics <br> <input type="checkbox" value="content" id="content" />In contents <br> <input type="checkbox" value="content" id="content" />In tags <br>Between <input type="text" type="text" class="datepicker" /> </div> <div id="right_col"> <br> <br> <br>and <input type="text" type="text" class="datepicker" /> <br/> </div> </div> </div> </div> <div class="content container" style="padding-top: 50px"> <div class="row"> <div class="col-md-8 col-centered"> <div class="post" data-ng-repeat="post in postList | bytitle : filterTerm "> <div class="date">published: {{post.published_at | date:'dd-MM-yyyy, HH:mm'}}</div> <a class="btn btn-default" data-ng-click="editPost(post)"><span class="glyphicon glyphicon-pencil"></span></a> <a class="btn btn-default" data-ng-click="deletePost(post)"><span class="glyphicon glyphicon-remove"></span></a> <h1><a href="">{{post.title}}</a></h1> <p>{{post.text}}</p> </div> </div> <div class="col-md-4 col-centered"> <h1>New post</h1> <form class="post-form"> <h4>Title:</h4> <p> <input type="text" name="title" data-ng-model="title"> </p> <h4>Text:</h4> <p> <textarea name="text" data-ng-model="text"></textarea> </p> <button type="submit" class="save btn btn-default" ng-click="addPost()">Save</button> <button type="reset" class="btn btn-default">Clear</button> <button type="button" class="btn btn-default" ng-click="cancelEdit()">Cancel edit</button> </form> </div> </div> </div> </div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.