0
<nav>
<ul class="list">
    <li ng-repeat="product in data | startFrom:currentPage*pageSize | limitTo:pageSize">
    <span>{{product}}</span>
        <a href="#getAttributes/{{product}}/{{code}}/{{name}}/{{hierName}}">
        {{product.prd_name}}

        </a>
    </li>
</ul>
</nav>

I am calling the ng-route as above .

myApp.config([ '$routeProvider', function($routeProvider) {
$routeProvider
.when('/getAttributes/:product/:code/:name/:hierName', {
    templateUrl : 'view/attributes.jsp',
    controller : 'attributeController'
}).otherwise({
    redirectTo : '/mainMenu'
});
} ]);

The Product is a JSON Object. The above code routes to otherwise if the product object contains "/" character. Any idea on how to resolve it.

4

1 回答 1

1

First Approach: Use ng-click to Store the Model In A Service Then Go to Location

Start by adding an ng-click to your list item which calls get attributes on your controller taking caring to remove the href.

<nav>
    <ul class="list">
        <li ng-repeat="product in data | startFrom:currentPage*pageSize | limitTo:pageSize" ng-click="getAttributes(product)">
            <span>{{product}}</span>
                <a href="">{{product.prd_name}}</a>
        </li>
    </ul>
</nav>

Next, reconfigure your route to simply /getAttributes

myApp.config([
    '$routeProvider', function($routeProvider) {
        $routeProvider
            .when('/getAttributes/', {
                templateUrl: 'view/attributes.jsp',
                controller: 'attributeController'
            }).otherwise({
                redirectTo: '/mainMenu'
            });
    }
]);

In your controller, add a method called getAttributes which will be invoked by the aforementioned ng-click. It will call a service and use its setModel function to persist which model was clicked. Finally, it will route getAttributes.

myApp.controller('someController', [
    '$scope', '$location', 'someService', function($scope, $location, someService) {
        $scope.getAttributes = function(model) {
            someService.setModel(model);
            $location.url('getAttributes');
        };
    }
]);

The attribute controller will call the same service and use its getModel method to set the model.

myApp.controller('attributeController', [
    '$scope', 'someService', function($scope, someService) {
        $scope.model = someService.getModel();
    }
]);

The service would like something like the following:

myApp.service('someService', function() {
    var model;

    return {
        getModel: function() {
            return model;
        },
        setModel: function(newModel) {
            model = newModel;
        }
    };
});

This approach is only suitable if you'll never be routing to getAttributes in any other way. A more flexible second approach is possible.

Second Approach: Use Resolve to Get the Model, Set In the Service Then Load in the Controller

Modify the href to be an ng-href and have it be getAttribute/123 or some such.

    <nav>
        <ul class="list">
            <li ng-repeat="product in data | startFrom:currentPage*pageSize | limitTo:pageSize">
                <span>{{product}}</span>
                <a ng-href="/getAttributes/{{product.id}}">{{product.prd_name}}</a>
            </li>
        </ul>
    </nav>

Modify your route to accept the product ID as seen below. Additionally, add a resolve object. This object will call someService which will in turn call your server, retrieve the products attributes and set the model variable equal to the result.

myApp.config([
    '$routeProvider', function($routeProvider) {
        $routeProvider
            .when('/getAttributes/:id', {
                templateUrl: 'view/attributes.jsp',
                controller: 'attributeController',
                resolve: {
                    getModel: function(someService) {
                        return someService.get();
                    }
                }
            }).otherwise({
                redirectTo: '/mainMenu'
            });
    }
]);

As mentioned before, the service will take the passed ID on the /getAttributes/id route and use it to call the server. An alternative is to have the service call a repository for this instead. The end result is the same: set the model variable equal to the result of the call to the server.

myApp.service('someService', [
    '$http', function($http) {
        var model;

        return {
            get: function(id) {
                return $http.get('api/attribute/' + id).then(function(response) {
                    model = response.data;
                });
            },
            getModel: function() {
                return model;
            },
            setModel: function(newModel) {
                model = newModel;
            }
        };
    }
]);

Finally, your attributeController will behave the same as the first example. It set $scope.model equal to someService.getModel() thereby providing the products attributes.

The advantage to this approach is that your route may deep linked from anywhere in your app without issue.

于 2014-07-15T18:26:23.553 回答