2

Note this question is a bit different from the similar titled here or here. What I want to do is to "evaluate inside the HTML tag" not inside a directive (or in the controller). This description can be wrong or hard to understand but I cannot find a better way; so I made bellow self-contained code to illustrate. You may copy and past and save as "xyz.html" and see what I mean.

<!DOCTYPE html>
<html ng-app="myApp">
  <head>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular.min.js"></script>
    <script>
      'use strict';
      let app = angular.module('myApp', []);
      app.controller('myCtrl', ['$scope', function ($scope) {
        let d = DATA_TYPE;
        let e = EDIT_TYPE;
        $scope.tbContents = {
          fields: [
            {name: 'name', dataType: d.text, editType: e.text, refs:[]},
            {name: 'catalog', dataType: d.text, editType: e.dropdown, refs: ['catalog1', 'catalog2', 'catalog3']},
            {name: 'status', dataType: d.int, editType: e.dropdown, refs: [1, 2, 3, 4]}],
          rows: [
            {name: 'name1', catalog: 'catalog1', status: 1},
            {name: 'name2', catalog: 'catalog1', status: 1},
            {name: 'name3', catalog: 'catalog2', status: 2}
          ]
        };
        $scope.refNameKey = '';
        $scope.setRefNameKey = function(key) {
          $scope.refNameKey = key;
        };
        $scope.getRefByNameKey = function(key) {
          let res = [];
          for(let i = 0; i < $scope.tbContents.fields.length; i++) {
            if($scope.tbContents.fields[i].name == key) {
              return $scope.tbContents.fields[i].refs;
            }
          }
        };
      }]);

      app.filter('filterDropdown', function () {
        return function (fields) {
          let output = [];
          for (let i = 0; i < fields.length; i++) {
            if (fields[i].editType == EDIT_TYPE.dropdown) {
              output.push(fields[i]);
            }
          }
          return output;
        };
      });

      const DATA_TYPE = {
        int: 1,
        text: 2,
        //...
      };

      const EDIT_TYPE = {
        dropdown: 1,
        test: 2,
        //...
      };
    </script>
  </head>

  <body>
    <div ng-controller="myCtrl">
      <div>
        <!--<p ng-repeat="field in tbContents.fields | filterDropdown"><a href="#" ng-click="refNameKey=field.name">{{field.name}}</a></p>-->
        <p ng-repeat="field in tbContents.fields | filterDropdown"><a href="#" ng-click="setRefNameKey(field.name)">{{field.name}}</a></p>
      </div>
      <hr />
      <div ng-show = "refNameKey">
        <p ng-repeat = "ref in getRefByNameKey(refNameKey)">{{ref}}</p>
      </div>
    </div>
  </body>
</html>

What I want is the line I commented in the HTML code, refNameKey=field.name instead of setRefNameKey(field.name). I don't know why refNameKey=field.name does not work, but I don't like creating the setRefNameKey function for this simple task.

Aleksey Solovey
  • 4,153
  • 3
  • 15
  • 34
zipper
  • 377
  • 1
  • 5
  • 18

1 Answers1

1

ng-repeat creates child scope for each iteration. So your refNameKey variable is created in each child scope and its not referring to the refNameKey in parent scope. You can fix this by modifying it like this:

<p ng-repeat="field in tbContents.fields | filterDropdown"><a href="#" ng-click="$parent.refNameKey=field.name">{{field.name}}</a></p>

Plunker : http://plnkr.co/edit/mcDvGqd6SFCfmqyfUNRc?p=preview

Vijay Venugopal Menon
  • 1,510
  • 1
  • 14
  • 20