简体   繁体   中英

angular.js: How to use templates and JSON for building a SPA

I'm using angular.js to create a SPA. I need your advise which technique I have to use for showing the informations/articles.

My index.html looks like this:

<body>
    <header id="navigation">
        <nav id="main">
            <ul>
                <li id="login"><button class="btn">Login</button></li>
            </ul>
        </nav>
    </header>
    <main>

    </main>
    <footer>
        <p>Some text</p>
    </footer>
</body>

At the beginning this HTML (using the directive angucomplete-alt) should be shown in the main-container:

autocomplete-search-template.html:

<div>Any content</div>
<div id="searching" ng-controller='search'>
    <div angucomplete-alt id="s1" selected-object="select" remote-url="search.php?q=" remote-url-data-field="results" title-field="title" description-field="description"></div>
</div>

When the user is searching for an article the following controller is used:

controller:

app.controller('search', ['$scope', '$http',
    function s1($scope, $http) {

        $scope.select = function(selected) {
            if (selected) {
                /* Article has been chosen */
            }
        };

    }
]);

The article-template.html looks like this and should be inserted into the main-container, after the user has selected an article in the search (angucomplete-alt:

article-template.html:

<article>
    <header>{{title}}</header>
    <div>{{content}}</div>
</article>

Now I don't know how I should put this parts together and therefore I need your help.

  1. How do I put these templates together? (a) Do I have to use routing or is there another technique? If I have to use routing, then I don't know how to get from the search-result to the article-display as it is no href-link... (b) Or would it be better to use ng-include (c) Or another option?
  2. Where (and when) do I get the article informations? I think I have to use a http-post request to get a JSON-array which will be used to fill the placeholders of article-template.html. So I thought of doing a request in the $scope.select . But there is still my problem of merging everything together

Update Routing:

app.config(function($routeProvider) {
    $routeProvider
    .when('/search', {
        templateUrl: 'autocomplete-search-template.html',
        controller: 'search'
    })
    .otherwise({
        redirectTo: '/search'
    });
});

This is working to show the autocomplete-search-template.html at the frontpage. But I don't know how to route for the results of the angucomplete-alt search.

With Angular ui-router you can use a nested view for your search result.

To get your data before the view is loaded you can use resolve to get the data from server. Then you can inject the resolved promise into you controller and use the returned data in your nested view.

With $state.go('search.article', {foundArticle: $scope.selectedPerson}); you can pass the selected item from angucomplete to the nested view.

To make the paramter passing work you need to add the following to the nested view:

$stateProvider.state('search.article', {
    ...
    params:{foundArticle:null},
    controller: function ($scope, $stateParams) {
        $scope.article = $stateParams.foundArticle;
    }
}

For an example of the usage see the demo below (code not working here on SO - 'operation is insecure' issue. Don't know how to fix.) and here at jsFiddle .

The code could be improved at the following points:

  • Using a service for getting the data.
  • If your articles are large you probably need to do another resolve at transition to the article and load at pageload only the needed data. The demo loads everything at the beginning.

 angular.module('myApp', ['ui.router', 'angucomplete-alt']) .controller('search', function ($scope, $state, searchData) { //console.log(searchData.data); $scope.people = searchData.data; // static dummy data below /*$scope.people = [ {firstName: "Susan", surname: "Rowland", twitter: "@susanrowland", pic: "http://lorempixel.com/100/100/people/1/", content: 'text for Susan'}, {firstName: "Alan", surname: "Partridge", twitter: "@alangpartridge", pic: "http://lorempixel.com/100/100/people/3/", content: 'text for Alan'}, {firstName: "Annie", surname: "Rowland", twitter: "@anklesannie", pic: "http://lorempixel.com/100/100/people/6/", content: 'text for Annie'} ];*/ $scope.select = function(selected) { if (selected) { console.log(selected, $state); /* Article has been chosen */ $scope.selectedPerson = selected; // same as two-way binding $state.go('search.article', {foundArticle: $scope.selectedPerson}); } }; }) .config(function ($stateProvider, $urlRouterProvider) { // // For any unmatched url, redirect to /state1 $urlRouterProvider.otherwise("/search"); // // Now set up the states $stateProvider.state('search', { url: "/search", resolve: { searchData: function ($http) { return $http.jsonp('http://www.mocky.io/v2/554f135e539c140e02858ff7/?callback=JSON_CALLBACK'); } }, templateUrl: "partials/search.html", controller: 'search' }) .state('search.article', { url: "/article", params:{foundArticle:null}, templateUrl: "partials/search.article.html", controller: function ($scope, $stateParams) { $scope.article = $stateParams.foundArticle; } }) }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.14/angular-ui-router.min.js"></script> <script src="https://raw.githubusercontent.com/ghiden/angucomplete-alt/master/dist/angucomplete-alt.min.js"></script> <script type="text/ng-template" id="partials/search.html"> <!-- partials/state1.html --> <h1>Search users (eg Rowland)</h1> <hr/> <!--<a ui-sref="state1.list">Show List</a>--> <div angucomplete-alt id="ex2" placeholder="Search people" pause="300" selected-object="select" local-data="people" search-fields="firstName,surname" title-field="firstName,surname" description-field="twitter" image-field="pic" minlength="1" input-class="form-control form-control-small" match-class="highlight"> </div> <div class="result"> <div class="" ng-show="selectedPerson" > You selected <span class="bold-span">{{selectedPerson.originalObject.firstName}} {{selectedPerson.originalObject.surname}}</span> </div> </div> <div ui-view></div> </script> <script type="text/ng-template" id="partials/search.article.html"> <h3>Found article</h3> <article> <header>{{article.title}}</header> <div> <p>{{article.originalObject.content}}</p> <pre>{{article | json}}</pre></div> </article> </script> <div ng-app="myApp"> <div ui-view=""></div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM