`

AngularJS应用GubHub

阅读更多

        AngularJS实例GutHub是一款简单管理应用,主要的特性如下:

1.两列布局

2.在左侧有一个导航条

3.允许你创建新菜谱

4.允许你浏览现有的菜谱列表

        主视图位于右侧,主视图将会根据具体的URL刷新,可以显示菜谱列表、菜谱项目详情,以及用来添加或编辑菜谱的表单。

        本文源码下载地址:https://github.com/johnnymitrevski/gutHub

工程结构图:

controllers.js

//Setup the GutHub angular module
var app = angular.module('guthub', ['guthub.directives', 'guthub.services']);

//Update the baseUrl to match the directory the app is deployed on the web server. Leave blank if '/'.
var baseUrl = "";

/**
 * Specify the various routes we have in our application. For each route we specify:
 * 1) The controller that backs it up.
 * 2) The template to load.
 * 3) The resolve object (Optional). This tells angular JS that each of the resolve keys need to be meet
 * before the route can be displayed to  the user. For us, we want to load all the recipe data before we
 * display the page. If the resolve function returns a $q (promise) then AngularJs is smart enough to wait
 * for the promise to get resolved before it proceeds. That means wait till the server responds.
 */
app.config(['$routeProvider', function($routeProvider) {

    $routeProvider.when('/', {
        controller: 'ListCtrl',

        resolve: {
            recipes: function(MultiRecipeLoader) {
                return MultiRecipeLoader();
            }
        },
        templateUrl: baseUrl + '/GutHub/views/list.html'
    }).when('/edit/:recipeId', {
            controller: 'EditCtrl',
            resolve: {
                recipe: function(RecipeLoader) {
                    return RecipeLoader();
                }
            },
            templateUrl: baseUrl + '/GutHub/views/recipeForm.html'
        }).when('/view/:recipeId', {
            controller: 'ViewCtrl',
            resolve: {
                recipe: function(RecipeLoader) {
                    return RecipeLoader();
                }
            },
            templateUrl: baseUrl + '/GutHub/views/viewRecipe.html'
        }).when('/new', {
            controller: 'NewCtrl',
            templateUrl:baseUrl + '/GutHub/views/recipeForm.html'
        }).otherwise({redirectTo: '/'});
}]);

/**
 * List the recipes
 */
app.controller('ListCtrl',['$scope','recipes',function($scope, recipes) {
    //$scope.recipes = recipes;
	$scope.recipes = [
	   { id:1, title:"cookies", description: "Delicious, crisp on the outside, chewy" + " on the outside, oozing with chocolatey goodness " + "cookies. The best kind", ingredients: [ { amount: "1", amountUnits: "packet", ingredientName: "Chips Ahoy" } ], instructions: "1. Go buy a packet of Chips Ahoy\ n" + "2. Heat it up in an oven\ n" + "3. Enjoy warm cookies\ n" + "4. Learn how to bake cookies from somewhere else" }
	];
}]);

/**
 * View a recipe
 */
app.controller('ViewCtrl', ['$scope','$location','recipe', function($scope, $location, recipe) {
    $scope.recipe = recipe;
    $scope.edit = function() {
        $location.path('/edit/' + recipe.id);
    };
}]);

/**
 * Exposes save() and remove() functions to scope.
 *
 * save() will save the current recipe and then redirect to the view screen
 * of the same recipe.
 *
 * remove() removes the recipe from the scope and redirects the uses to the
 * main landing page.
 */
app.controller('EditCtrl', ['$scope','$location','recipe', function($scope, $location, recipe) {

    $scope.recipe = recipe;

    $scope.save = function() {
        $scope.recipe.$save(function(recipe){
            $location.path(baseUrl + '/GutHub/view/' + recipe.id);
        });
    };

    $scope.remove = function() {
        delete $scope.recipe;   //Doesn't remove it from the server. Only from $scope.

        $location.path(baseUrl + '/');
    };
}]);

/**
 * Create a new recipe.
 */
app.controller('NewCtrl',['$scope', '$location', 'Recipe', function($scope, $location, Recipe){
    $scope.recipe = new Recipe({
        ingredients: [{}]
    });

    $scope.save = function() {
        $scope.recipe.$save(function(recipe) {
            $location.path(baseUrl + '/view/' + recipe.id);
        });
    };
}]);

/**
 * Edit the ingredients. It inherits $scope from the parent controller.
 */
app.controller('IngredientsCtrl', ['$scope', function($scope) {

    $scope.addIngredient = function() {
        var ingredients = $scope.recipe.ingredients;
        ingredients[ingredients.length] = {};
    };

    $scope.removeIngredient = function(index) {
        $scope.recipe.ingredients.splice(index, 1);
    };
}]);

directives.js

var directives = angular.module('guthub.directives',[]);

directives.directive('butterbar',['$rootScope', function($rootScope){
    return {
        link: function(scope, element, attrs) {

            element.addClass('hide'); //Hide the element upfront

            //Watch the $routeChangeStart and remove the hide css, therefore show
            $rootScope.$on('$routeChangeStart', function() {
                element.removeClass('hide');
            });

            //Watch the $routeChangeSuccess and remove add the hide css, therefore hide
            $rootScope.$on('$routeChangeSuccess', function() {
                element.addClass('hide');
            });
        }
    };
}]);

/**
 * Calls the focus() method on the current element.
 *
 * Call it by adding the focus attribute on any input element.
 * i.e. <input type="text" focus></input>
 * Therefore when the page loads, that element immediately gets the focus.
 */
directives.directive('focus', function() {
    return {
        link: function(scope, element, attrs) {
            element[0].focus();
        }
    };
});

services.js

var services = angular.module('guthub.services',['ngResource']);

/**
 * Recipe service.
 *
 * Uses $resource, which is is a RESTful handle that encapsulates lower level $http service.
 *
 * Recipe can now be used an argument injected into our controllers. The following methods are built in:
 * Recipe.get();
 * Recipe.save();
 * Recipe.delete();
 * Recipe.remove();
 * Recipe.delete();
 *
 * Useage: if we pass in an object with an id field, then the value of that field will be
 * added to the end of the URL.
 * Calling Recipe.get({id:15}) will make a call to /recipes/15
 *
 * For example:
 * var recipe = new Recipe(existingRecipeObj);
 * recipe.$save(); - this calls a POST request
 */
services.factory('Recipe',['$resource', function($resource){
    return $resource('/GutHub/recipes/:id',{id: '@id'});
}]);

/**
 * Load all recipes.
 */
services.factory('MultiRecipeLoader', ['Recipe', '$q', function(Recipe,$q){
    return function() {
        var delay = $q.defer();

        Recipe.query(function(recipesData) {
            delay.resolve(recipesData);
        }, function() {
            //delay.reject('Unable to fetch recipes');
            delay.resolve([{id:1, title:"cookies"}, {id:2, title:"farts"}]);
        });

        return delay.promise;
    };
}]);

/**
 * Load a single recipe.
 */
services.factory('RecipeLoader', ['Recipe','$route', '$q', function(Recipe, $route, $q){
    return function() {
        var delay = $q.defer();
        Recipe.get({id: $route.current.params.recipeId}, function(recipeData) {
            delay.resolve(recipeData);
        }, function() {
            //delay.reject('Unable to fetch recipe ' + $route.current.params.recipeId);
            delay.resolve({ id:1, title:"cookies", description: "Delicious, crisp on the outside, chewy" + " on the outside, oozing with chocolatey goodness " + "cookies. The best kind", ingredients: [ { amount: "1", amountUnits: "packet", ingredientName: "Chips Ahoy" } ], instructions: "1. Go buy a packet of Chips Ahoy\ n" + "2. Heat it up in an oven\ n" + "3. Enjoy warm cookies\ n" + "4. Learn how to bake cookies from somewhere else" });
        });

        return delay.promise;
    }
}]);

index.html

<!DOCTYPE html>

<html lang="en" ng-app="guthub">
<head>
<title>GutHub - Create and Share</title>
<script src="scripts/vendor/angular.js"></script>
<script src="scripts/vendor/angular-resource.js"></script>
<script src="scripts/directives/directives.js"> </script>
<script src="scripts/services/services.js"> </script>
<script src="scripts/controllers/controllers.js"></script>
<link href="scripts/vendor/bootstrap/css/bootstrap.css" rel="stylesheet">
</head>
<body>
    <header>
        <h1>GutHub</h1>
    </header>
    <div butterbar>Loading...</div>

    <div class="container-fluid">
        <div class="row-fluid">
            <div class="span2">
            <!--Sidebar-->
            <div id="focus">
                <a href="#/new">New Recipe</a>
            </div>
            <div>
                <a href="#/">Recipe List</a>
            </div>
            </div>
            <div class="span10">
                <div ng-view></div>
            </div>
        </div>
    </div>
</body>
</html>

list.html

<h3>Recipe List</h3>
<ul class="recipes">
    <li ng-repeat="recipe in recipes">
        <div>
            <a href="#/view/{{ recipe.id }}">{{ recipe.title }}</a>
        </div>
    </li>
</ul>

recipeForm.html

<h2>Edit Recipe</h2>

<form name="recipeForm" ng-submit="save()" class="form-horizontal">
    <div class="control-group">
        <label class="control-label" for="title">Title:</label>
        <div class="controls">
            <input ng-model="recipe.title" class="input-xlarge" id="title" focus>
        </div>
    </div>
    <div class="control-group">
        <label class="control-label" for="description">Description:</label>
        <div class="controls">
            <textarea ng-model="recipe.description" class="input-xlarge" id="description"></textarea>
        </div>
    </div>
    <div class="control-group">
        <label class="control-label" for="ingredients">Ingredients:</label>
        <div class="controls">
            <ul id="ingredients" class="unstyled" ng-controller="IngredientsCtrl">
                <li ng-repeat="ingredient in recipe.ingredients">
                    <input ng-model="ingredient.amount" class="input-mini">
                    <input ng-model="ingredient.amountUnits" class="input-small">
                    <input ng-model="ingredient.ingredientName">
                    <button type="button" class="btn btn-mini" ng-click="removeIngredient($index)">
                        <i class="icon-minus-sign"></i>
                        Delete
                    </button>
                </li>
                <button type="button" class="btn btn-mini" ng-click="addIngredient()">
                    <i class="icon-plus-sign"></i>
                    Add
                </button>
            </ul>
        </div>
    </div>

    <div class="control-group">
        <label class="control-label" for="instructions">Instructions:</label>
        <div class="controls">
            <textarea ng-model="recipe.instructions" class="input-xxxlarge" id="instructions"></textarea>
        </div>
    </div>

    <div class="form-actions">
        <button class="btn btn-primary">Save</button>
        <button type="button" ng-click="remove()" ng-show="!recipe.id" class="btn">
            Delete
        </button>
    </div>
</form>

viewRecipe.html

<h2>{{ recipe.title }}</h2>
<div>{{ recipe.description }}</div>

<h3>Ingredients</h3>
<ul class="unstyled">
    <li ng-repeat="ingredient in recipe.ingredients">
        <span>{{ ingredient.amount }}</span>
        <span>{{ ingredient.amountUnits }}</span>
        <span>{{ ingredient.ingredientName }}</span>
    </li>
</ul>

<h3>Instructions</h3>
<div>{{ recipe.instructions }}</div>

<form ng-submit="edit()" class="form-horizontal">
    <div class="form-actions">
        <button class="btn btn-primary">Edit</button>
    </div>
</form>

运行效果(由于没有编写后台,不少地方会报错甚至不能成功运行):





附:GitHub上下载的工程源代码和用SeaJS组织的工程源代码

  • 大小: 35 KB
  • 大小: 14 KB
  • 大小: 43.9 KB
  • 大小: 40.5 KB
  • 大小: 33.5 KB
分享到:
评论

相关推荐

    组件式AngularJS应用示例Phonecat用现代Javascript和Webpack实现

    **组件化AngularJS应用——Phonecat的现代JavaScript与Webpack实现** 在现代Web开发中,组件化已经成为构建可维护、可复用和可扩展应用程序的重要模式。AngularJS,一个由Google维护的JavaScript框架,以其强大的...

    AngularJS教程之简单应用程序示例

    AngularJS是一个由谷歌维护的开源前端JavaScript框架,用于构建动态网页应用程序。它通过使用HTML作为模板语言,引入了数据绑定、依赖注入、多组件支持等特性,从而简化了前端开发。本文将通过一个简单示例程序来...

    AngularJS应用ppt

    AngularJS应用ppt,AngularJS应用ppt,AngularJS应用ppt

    angularjs-style-guide, 社区驱动的AngularJS应用程序开发最佳实践集.zip

    angularjs-style-guide, 社区驱动的AngularJS应用程序开发最佳实践集 简介这个样式指南的目标是为一个AngularJS应用程序提供一套最佳实践和风格指南。 这些最佳做法是从以下位置收集的:AngularJS源代码我已经阅读的...

    angular-autolayout, 基于约束的AngularJS应用程序布局.zip

    angular-autolayout, 基于约束的AngularJS应用程序布局 AngularJS的自动布局基于约束的AngularJS布局范例 AngularJS AngularJS inspired inspired inspired iOS iOS的inspired Auto 。HTML和CSS设计用来呈现

    angular-debaser, 一个更好的测试AngularJS应用程序的方法.zip

    angular-debaser, 一个更好的测试AngularJS应用程序的方法 角 debaser 一个更好的测试AngularJS应用程序的方法。这个想法AngularJS及其依赖注入使得在测试中隔离代码变得非常容易。不幸的是,为这些服务编写存根可以...

    花钱买来的angularjs模板bonanzooka管理页面angularjs应用程序后台模板

    AngularJS是一款由Google维护的前端JavaScript框架,常用于构建单页应用(SPA,Single Page Applications)。这个名为"bonanzooka"的管理页面模板是基于AngularJS开发的,旨在为后端管理员提供一个用户界面友好、...

    用AngularJS开发下一代Web应用(AngularJS 2013)-中英双版本

    本资源提供了2013年的"用AngularJS开发下一代Web应用"的中英双版本电子书,旨在帮助开发者深入了解和掌握AngularJS的核心概念和技术。 在AngularJS中,双向数据绑定是最显著的特点之一。它使得模型和视图之间的数据...

    使用AngularJS开发下一代WEB应用

    资源名称:使用AngularJS开发下一代WEB应用内容简介:用AngularJS开发下一代Web应用的作者是两位在Google负责AngularJS框架的工程师,他们将引领读者概览整个框架的核心特性,并构建一款可运行的AngularJS应用,内容...

    用AngularJS开发下一代web应用pic

    AngularJS,是由Google维护的JavaScript框架,用于构建交互式的单页应用程序(SPA)。它通过提供数据绑定和依赖注入等核心特性,极大地简化了前端开发流程,使得开发者可以更专注于业务逻辑,而非DOM操作。本教程将...

    AngularJS Eclipse 1.2.0 插件下载

    AngularJS Eclipse 1.2.0 插件是专为开发者设计的一款强大的工具,它将AngularJS框架与Eclipse集成,极大地提升了开发AngularJS应用程序的效率。Eclipse是一款广泛使用的开源集成开发环境(IDE),而AngularJS则是一...

    AngularJS Web Application Development Cookbook

    《AngularJS Web 应用开发食谱》是由Matt Frisbie编写的经典编程书籍,它提供了90多个实用的食谱来帮助开发者构建高性能的AngularJS应用,并实施最佳实践。这本书在Amazon上获得了5星的高评价,显示出其在开发者群体...

    用AngularJS开发下一代Web应用.pdf

    AngularJS是由Google开发的开源前端JavaScript框架,它被设计为创建动态网页应用提供一套丰富工具,尤其是单页应用(SPA)。AngularJS的出现,标志着Web应用开发步入了新的阶段,它通过引入了诸多创新概念和方法来...

    angularjs-style-guide-github

    AngularJS是一种流行的前端JavaScript框架,它允许开发者利用它的MVC(模型-视图-控制器)特性来构建复杂的、单页的web应用。AngularJS的代码风格指南是用来指导开发者如何编写一致、可维护、高效的代码的一套规则和...

    Angularjs 合集 Angularjs 合集

    AngularJS 是一款由Google维护的前端JavaScript框架,用于构建单页Web应用(SPA,Single Page Applications)。这个合集包含了三本书籍,分别是《AngularJS by Example》、《AngularJS Web Application Development ...

Global site tag (gtag.js) - Google Analytics