Ramosta
Ramosta

Reputation: 647

Expression in ng-controller for a JSON-Objects with AngularJS and Ionic

I parse JSON objects to create html elements. In my case, I create from json file Buttons:

{
    "type": "button",
    "id": "comButton",
    "icon": "ion-chatboxes",
    "name": "Communication",
    "onclick": "",
    "controller": "somemthctrl",
    "ngclick": "launchSomemethod()",
    "color": "white",
    "backgroundcolor": "#ff5db1",
    "font-size": "20px"
}

Controller:

myApp.controller('generateButtonCtrl', function ($scope, $http) {
    $http.get('JSON/buttons.json').success(function(data){
        $scope.components = data;
    });
});

From the HTML page, I call the components from the json file:

<a ng-repeat="component in components"
   style="color:{{component.color}}; background-color:{{component.backgroundcolor}} "
   id="{{component.id}}"
   class="{{component.type}}"
   href="{{component.onclick}}"
   ng-click="{{component.ngclick}}"
   ng-controller="{{component.controller}}">

    <i class="{{component.icon}}"><br></i>
    {{component.name}}
</a>

In the case ng-click="{{component.ngclick}}" und ng-controller="{{component.controller}}" will not be included.

At the appropriate places I get from my editor WebStorm following error: Identifier or String literal or numeric literal expected.

I have a {{expression}} Problem. How can I integrate the ng-controller and ng-click as a string from a json object?

Upvotes: 0

Views: 1055

Answers (2)

NiRUS
NiRUS

Reputation: 4259

This is quite tricky. Angular team on their doc suggests that controller should be registered to a module while the DOM is being parsed.

All the $scope properties will be available to the template at the point in the DOM where the Controller is registered.

Link: Angular controllers


  • Use $controllerProvider to register the controller This link shed's some light on how controllers are resolved at later point of the time, which might help you in designing your code as desired.
  • ng-click you can give an expression or a method which is inside the controller of $scope tree. Both the expression and/or function search happens inside the $scope tree at the compile time of your template.

Update As per the fiddler requested


I have corrected the fiddler code, removed unwanted lines, errors and made it working.

Now your template is dynamic binding to the JavaScript code at the run-time.

Fiddler Link

Javascript:

 var myApp = angular.module('starter', []);
myApp.config(['$sceDelegateProvider', function($sceDelegateProvider) {
    $sceDelegateProvider.resourceUrlWhitelist([
        'self',
        'https://api.myjson.com/**'
    ]);
}]);

myApp.controller('generateHTMLCtrl', function ($scope, $http, $compile, $interpolate, $templateCache) {
    $http.get('https://api.myjson.com/bins/1gkh0').success(function (data) {      
        for(var i in data){
            var interpolated = $interpolate($templateCache.get("tpl").trim())(data[i]);            
            angular.element(document.querySelector("#loadhere")).append($compile(interpolated)($scope));            
        }               
    });
});

myApp.controller("OpenLinkCtrl", function ($scope) {    
        $scope.OpenLink = function () {
           alert("Link open");
        }    
});

Html:

 <body ng-app="starter" class="padding" style="text-align: center">
 <div class="row responsive-md" ng-controller="generateHTMLCtrl" id="loadhere"></div>                                        
 <script type="text/ng-template" id="tpl">
                 <div class="col">
                    <a style="color:{{color}}; background-color:{{backgroundcolor}} "
                       id="{{id}}" class="{{type}}" href="{{topage}}" ng-controller="{{controller}}" ng-click="{{function}}"><i class="{{icon}}"><br></i>{{name}}</a>
                </div>
          </script>
    </body>

Explanation:

  • Used interpolate service
  • Used compiler service

Note: Interpolator cannot parse on array of objects. Hence used for loop to interpolate each oject array and append it to the DOM.

More info on compiler and interpolation can be found here

Upvotes: 2

davesnx
davesnx

Reputation: 384

I'm not sure that it's possible the ng-controller could be a {{ expression }}. The workarround it's creating a function that returns the name of the controller that you want and you can assign to a var inside the controller...

In other case, why you want to use a different controller for each button?

Upvotes: 0

Related Questions