2013-04-14 13 views
7

Pracowałem nad samouczkiem Angular.js, który teraz chcę rozszerzyć. Jest to prosta aplikacja CRUD z listą szablonów: list.html (tylko rekordy w db z tytułem i treścią), formularzem tworzenia: new.html i formularzem edycji: edit.html.Wiele niezależnych części w AngularJS

Właśnie teraz list.html ładuje tablicę szablonów z mojej aplikacji REST i wyświetla je w tabeli. Istnieje formularz wyszukiwania i niektóre funkcje sortowania.

New.html ma formularz do tworzenia nowych szablonów.

Te dwa pliki .html są ładowane przez przechodzenie do różnych tras. #/ i #/new

co chcę teraz zrobić, to mieć jeden plik index.html który ładuje zarówno list.html wewnątrz jednego div, a następnie new.html wewnątrz innego div. Chodzi o to, że lista zapisów zawsze będzie wyświetlana po lewej stronie, a pozostałe części będą ładowane w obszar po prawej stronie. Kliknięcie szablonu na liście otworzy go w obszarze obok listy, ale lista pozostanie nietknięta. Następnie, jeśli kliknę przycisk nowego szablonu, nowy formularz szablonu pojawi się ponownie w polu zawartości, ale lista pozostanie nietknięta.

Oto mój kod:

app.js

var MailStash = angular.module("MailStash", ["ngResource"]). 
    config(function($routeProvider){ 
     $routeProvider. 
      when('/', {controller: ListCtrl, templateUrl: '/js/partials/list.html'}). 
      when('/new', {controller: CreateCtrl, templateUrl: '/js/partials/new.html'}). 
      when('/edit/:editId', {controller: EditCtrl, templateUrl: '/js/partials/edit.html'}) 
    }); 

MailStash.factory('Template', function($resource){ 
    return $resource('/api/v1/template/:id', {id: '@id'}, { update: { method: 'PUT' } }); 
}); 

var EditCtrl = function($scope, $location, $routeParams, Template) { 
    $scope.action = "Update"; 

    var id = $routeParams.editId; 
    $scope.template = Template.get({id: id}); 

    $scope.save = function() { 
     Template.update({id: id}, $scope.template, function() { 
      $location.path('/'); 
     }); 
    }; 
} 

var CreateCtrl = function($scope, $location, Template) { 
    $scope.save = function() { 
     Template.save($scope.template, function(){ 
      $location.path('/'); 
     }); 
    } 
} 

var ListCtrl = function($scope, $location, Template) { 
    $scope.search = function() { 
     Template.query({ 
      q: $scope.query, 
      sort_order: $scope.sort_order, 
      is_desc: $scope.is_desc, 
      offset: $scope.offset, 
      limit: $scope.limit 
      }, 
      function(data){ 
       $scope.more = data.length === 20; 
       $scope.templates = $scope.templates.concat(data); 
      }); 
    } 

    $scope.sort = function(col) { 
     if($scope.sort_order === col) { 
      $scope.is_desc = !$scope.is_desc; 
     } else { 
      $scope.sort_order = col; 
      $scope.is_desc = false; 
     } 

     $scope.reset(); 
    }; 

    $scope.showMore = function(){ 
     $scope.offset += $scope.limit; 
     $scope.search(); 
    }; 

    $scope.hasMore = function(){ 
     return $scope.more; 
    } 

    $scope.reset = function() { 
     $scope.limit = 10; 
     $scope.offset = 0; 
     $scope.templates = []; 
     $scope.more = true; 

     $scope.search(); 
    } 

    $scope.delete = function() { 
     var id = this.template.id; 
     Template.delete({id: id}, function(){ 
      $('#template_'+id).fadeOut(); 
     }); 
    } 

    $scope.sort_order = "title"; 
    $scope.is_desc = false; 

    $scope.reset(); 
}; 

List.html:

<form class="form-search"> 
    <div class="input-append"> 
     <input type="text" ng-model="query" class="input-medium search-query" placeholder="Search"> 
     <button ng-click="reset()" type="submit" class="btn"><i class="icon-search"></i></button> 
    </div> 
    <button ng-click="query=''; reset()" ng-disabled="!query" type="submit" class="btn">Reset</button> 
</form> 
<p class="sort"> 
    Sort: 
    <a ng-click="sort('title')">Title</a> 
    <span ng-show="sort_order=='title' && is_desc==true"><i class="icon icon-arrow-down"> </i></span> 
    <span ng-show="sort_order=='title' && is_desc==false"><i class="icon icon-arrow-up"> </i></span> 
    &nbsp;|&nbsp; 
    <a ng-click="sort('created_at')">Date Created</a> 
    <span ng-show="sort_order=='created_at' && is_desc==true"><i class="icon icon-arrow-down"> </i></span> 
    <span ng-show="sort_order=='created_at' && is_desc==false"><i class="icon icon-arrow-up"> </i></span> 
</p> 
<table class="table"> 
    <tbody> 
     <tr ng-repeat="template in templates" id="template_{{template.id}}"> 
      <td>{{template.title}}</td> 
     </tr> 
    </tbody> 
</table> 
<a ng-show="hasMore()" ng-click="showMore()">Show more</a> 
<hr> 
<a href="/#/new" class="btn"><i class="icon icon-plus"> </i> New Template</a> 

New.html

<h2>New Template</h2> 
<form name="new_template"> 
    <div class="control-group" ng-class="{error: form.title.$invalid}"> 
     <div class="controls"> 
      <input type="text" class="span6" ng-model="template.title" name="title" id="title" value="" placeholder="Template name" /> 
     </div> 
    </div> 

    <div class="control-group" ng-class="{errors: form.content.$invalid}"> 
     <div class="controls"> 
      <textarea name="content" ng-model="template.content" id="content" class="template-content span12" rows="15"></textarea> 
     </div> 
    </div> 
    <div class="form-actions"> 
     <button ng-click="save()" class="btn btn-primary save-template">Save Template</button> 
    </div> 
</form> 

Mój plik układ:

<!DOCTYPE html> 
<html ng-app="MailStash" xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://ogp.me/ns/fb#"> 
    <head> 
     <title>MailStash</title> 
     <meta charset="utf-8"> 
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
     <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
     <meta name="author" content="Billy Jones - http://theninthnode.com"> 
     {{ Html::style('css/bootstrap.cerulean.min.css') }} 
     @yield('css') 
     {{ Html::style('css/style.css') }} 
    </head> 
    <body class="preview" data-spy="scroll" data-target=".subnav" data-offset="80"> 
     <div class="container-fluid"> 
      @include('common.header-fluid') 
     </div> 
     <div class="container-fluid main"> 
      <div ng-view></div> 
      @include('common.footer') 
     </div> 

     {{ HTML::script('js/jquery.min.js') }} 
     {{ HTML::script('js/bootstrap.min.js') }} 
     {{ HTML::script('js/angular.min.js') }} 
     {{ HTML::script('js/angular-resource.min.js') }} 
     {{ HTML::script('js/jquery.dataTables.min.js') }} 
     @yield('scripts') 
     {{ HTML::script('js/app.js') }} 
     {{ HTML::script('js/main.js') }} 
    </body> 
</html> 

Próbowałem użyć:

<div class="row-fluid"> 
    <div class="span3"> 
     <div ng-include="'/js/partials/list.html'"></div> 
    </div> 
    <div class="span9"> 
     <div ng-include="'/js/partials/new.html'"></div> 
    </div> 
</div> 

ale przegrałem funkcjonalność tych podszablonów. tj. formularz wyszukiwania przestał działać i nowy formularz szablonu przestał działać.

Odpowiedz

3

Myślę, że mówisz, że zastępujesz <div ng-view></div> ostatnim blokiem za pomocą 2 ng-include.

Jeśli tak, to prawdopodobnie nie potrzebują controller zdefiniowane w konfiguracji routingu i trzeba dodać ng-controller atrybutów html

+0

Nie ng-view zostały zachowane takie same. Załaduję plik index.html do widoku ng, określając szablon na trasie. A potem w środku próbowałem użyć ng-include do załadowania w dwóch osobnych plikach szablonów. Zastanawiam się 1. w jaki sposób mogę mieć 2 szablony działające niezależnie. 2. Jak uniknąć zepsucia istniejącego kodu? – iamjonesy

+0

Czy próbowałeś ustawić 'ng-controller' w każdym z' ng-include' zamiast w routerze config? – charlietfl

+0

Dodałem kontroler do ng-include, a niektóre funkcje powróciły. Problem polega na tym, że podczas wykonywania GET lub POST wszystkie moje parametry są wysyłane jako "niezdefiniowane" – iamjonesy

Powiązane problemy