[AngularJS] Soup to bits
1. Clone the angular-seed from git.
git clone https://github.com/angular/angular-seed.git
2. cd to the angular-seed and type:
npm install
3. type npm start to install bower and listen to a portcoal.
npm start
4. You can see that in cmd, it says listen on port 8000. For this you can chagne by yourself in package.json.
"start": "http-server -a localhost -p 8000 -c-1",
-----------------------------End start up----------------------------------------
'ng-repeat' on object:
We have data like books object, inside we still have genres object.
var books = [ { title: 'A Game of Thrones: A Song of Ice and Fire', author: 'George R.R. Martin', isbn: '0553593714', review: 'The most inventive and entertaining fantasy saga of our time—warrants one hell of an introduction. I loved this book!', rating: 4, genres: { 'non-fiction': true, fantasy: true } },{ title: 'HTML for Babies', author: 'John C Vanden-Heuvel Sr', isbn: '0615487661', review: "It's never too early to be standards compliant! I taught my little one mark-up in under one hour!", rating: 5, genres: { fiction: true } } ];
If we want to use ng-repeat on an object genres, we can do something like that:
<li ng-repeat="(genre, state) in genres" ng-show="state"> <span class="label label-primary">{{genre}}</span> </li>
Two-ways binding stuff:
.directive('bookGenres', function(){ return { restrict: 'E', templateUrl: 'partials/book-genres.html', scope: { genres: '=' } } })
in html:
<li class="book row" ng-repeat="book in readingListCtrl.books"> <book-cover></book-cover> <div class="col-sm-9"> <h3><a href="http://www.amazon.com/gp/product/{{book.isbn}}" >{{book.title}}</a></h3> <cite class="text-muted">Written by {{book.author}}</cite> <p>{{book.review}}</p> <book-genres genres="book.genres"></book-genres> /*Two ways binding here!!!*/ </div> </li>
Now we see 'genres' has binded to the 'book.genres'. Therefore for genres we can do:
<li ng-repeat="(genre, state) in genres" ng-show="state"> <span class="label label-primary">{{genre}}</span> </li>
Other example of two-ways binding:
.directive('reviewForm', function(){ return { restrict: 'E', templateUrl: 'partials/review-form.html', replace: true, controller: function(){ this.book = {genres:{}}; this.addReview = function(form){ books.push(this.book); this.book = {genres:{}}; form.$setPristine(); } }, controllerAs: 'reviewFormCtrl', scope: { books: '=', genres: '=' } } });
<review-form books="readingListCtrl.books" genres="readingListCtrl.genres" ng-show="readingListCtrl.showForm"></review-form>
directive -- replace: true: / use 'A'
Sometimes, when we create a E element directive such as:
<book-cover></book-cover>
.directive('bookCover', function(){ return { restrict: 'E', templateUrl: 'partials/book-cover.html' } })
So, what render to the html is something looks like: The book-cover tag is still here, and it is set as a block element by defualt.
Sometime, this breaks we layout. What we can do is use 'replace' tag in directive to remove the book-cover tag.
<book-cover><aside class="col-sm-3"> <a href="http://www.amazon.com/gp/product/0553593714"><img ng-src="http://images.amazon.com/images/P/0553593714.01.ZTZZZZZZ.jpg" alt="Cover of A Game of Thrones: A Song of Ice and Fire" class="full" src="http://images.amazon.com/images/P/0553593714.01.ZTZZZZZZ.jpg"></a> <p ng-class="{goodRating: book.rating >= 3}" class="rating ng-binding goodRating">4/5</p> </aside> </book-cover>
Therefore the directive would looks like:
.directive('bookCover', function(){ return { restrict: 'E', templateUrl: 'partials/book-cover.html' replace: true } })
And the html output will without book-cover tag.
Another way to fix the problem is use attribute tag 'A', to replace book-cover:
<!-- <book-cover></book-cover> --> <aside class="col-sm-3" book-cover></aside>
template: book-cover.html:
<a href="http://www.amazon.com/gp/product/{{book.isbn}}"><img ng-src="http://images.amazon.com/images/P/{{book.isbn}}.01.ZTZZZZZZ.jpg" alt="Cover of {{book.title}}" class="full"></a> <p ng-class="{goodRating: book.rating >= 3}" class="rating">{{book.rating}}/5</p>
Directive:
.directive('bookCover', function(){ return { restrict: 'A', templateUrl: 'partials/book-cover.html' // replace: true } })
controllerAs:
Sometime we add controller into a directive and if we want to access this controller. We can use controllerAs.
.directive('reviewForm', function(){ return { restrict: 'E', templateUrl: 'partials/review-form.html', replace: true, controller: function(){ this.book = {genres:{}}; this.addReview = function(form){ books.push(this.book); this.book = {genres:{}}; form.$setPristine(); } }, controllerAs: 'reviewFormCtrl', scope: { books: '=', genres: '=' } } });
Then in html you can access the function inside the controller by:
<button class="btn btn-default" ng-click="readingListCtrl.showForm = !readingListCtrl.showForm">{{readingListCtrl.showForm ? "Cancel" : "Create a Review"}}</button>
Checkbox & label:
lable's "for" should binded to input checkbox's id, they should be the same.
<div class="genre"> <label ng-repeat="genre in genres" for="{{genre}}" class="genre-label form-control"> <input type="checkbox" name="genre" id="{{genre}}" ng-model="reviewFormCtrl.book.genres[genre]" /> {{genre}} </label> </div>
ng-model access object inside object:
Here reviewFormCtrl.book is an object, genres is another object inside the book.
Therefore if we want to access geners object:
ng-model="reviewFormCtrl.book.genres[genre]"
Form story: init variable:
When you open the form, you really want to clear the things which you typed before.
Therefore, inside the controller do:
this.book = {genres:{}};
And the thing really need to be careful is genres is an obejct, anyobject inside another object you should define it first.
Form stroy: reset the form:
this.addReview = function(form){ books.push(this.book); this.book = {genres:{}}; form.$setPristine(); }
ng-class:
<p ng-class="{goodRating: book.rating >= 3}" class="rating">{{book.rating}}/5</p>
Understand how genres works in code:
In form we have checkbox:
<fieldset class="form-group"> <label class="control-label col-sm-2" >Genre:</label> <div class="genre"> <label ng-repeat="genre in genres" for="{{genre}}" class="genre-label form-control"> <input type="checkbox" name="genre" id="{{genre}}" ng-model="reviewFormCtrl.book.genres[genre]" /> {{genre}} </label> </div> </fieldset>
We bind the checkbox to the reviewFormCtrl.book.genres object by ng-model.
Because it is on a checkbox, so the value should be false or ture. When you select one checkbox, the value becomes to true.
And at the same time, we create a new genres object in genres. For exmaple:
reviewFormCtrl.book.genres[horroe] = true
Then in the live-preview, we repeat the genres inside only show when the status is true
<ul class="list-unstyled"> <li ng-repeat="(genre, state) in reviewFormCtrl.book.genres"> <span class="label label-primary" ng-show="state">{{genre}}</span> </li> </ul>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具