1

我想根据从后端收到的数据动态创建“组件”。目标是在不使用服务器端模板的情况下显示我的应用程序的一部分:服务器不是在服务器端显示组件,而是发送包含应该显示哪些组件的 JSON 数据。

这是我到目前为止所得到的:

var module = angular.module('testApp', []);

module.controller('Ctrl1', ['$scope', function ($scope) {
    $scope.test = "test 1";
}])
.controller('Ctrl2', ['$scope', function ($scope) {
    $scope.test = "test 2";
}])
.controller('ComponentsController', ['$scope', function ($scope) {
    // this is JSON returned by backend
    $scope.components = [{
        name: "Wd1",
        controller: "Ctrl1",
    }, {
        name: "Wd2",
        controller: "Ctrl2",
    }];

    $scope.test = "test";
}]);

我的观点:

<div ng-app="testApp">
    <div ng-controller="ComponentsController">
        <div ng-repeat="component in components">
            <p>{{component.name}} - {{component.controller}}</p>
        </div>

        <div ng-repeat="component in components">
            <p ng-controller="component.controller">{{test}}</p>
        </div>
    </div>
</div>

但是,我收到以下错误:

错误:参数“component.controller”不是函数,得到字符串

我试图编写一个指令,在编译期间分配控制器名称,但由于它是在编译期间完成的,它不适用于绑定......

这是一个小提琴:http: //jsfiddle.net/mathieu/bTQA5/

4

3 回答 3

0

将函数绑定到范围内的数据:

function ComponentsController($scope) {

    $scope.Ctrl1 = function () {
        $scope.test = "test 1";
    }

    $scope.Ctrl2 = function () {
        $scope.test = "test 2";
    }

    $scope.components = [{
        name: "Wd1",
        controller: $scope.Ctrl1
    }, {
        name: "Wd2",
        controller: $scope.Ctrl2
    }];

    $scope.test = "test";
}

这是更新的 jsFiddle

请注意,这里仍然存在逻辑问题;绑定将{{ test }}在控制器执行后立即进行评估,因此在我们的例子中,结果文本(在每个绑定上)将是最后一次评估,即"Test 2"

您可能希望将逻辑绑定到处理程序,例如ng-click,按需执行:

<div ng-repeat="component in components">
    <button ng-controller="component.controller" 
            ng-click="component.controller()">
        Call {{ component.name }} controller
    </button>
</div>

在这里也进行了现场演示


此答案基于此问题的第一个版本,其中包括以下代码:

function ComponentsController($scope) {
    $scope.components = [{
        name: "Wd1",
        controller: "Ctrl1",
    }, {
        name: "Wd2",
        controller: "Ctrl2",
    }];

    $scope.test = "test";
}

function Ctrl1($scope) {
    $scope.test = "test 1";
}

function Ctrl2($scope) {
    $scope.test = "test 2";
}
于 2013-07-21T18:10:41.213 回答
0

只需执行控制器名称,而不是字符串:

function ComponentsController($scope) {
    $scope.components = [{
        name: "Wd1",
        controller: Ctrl1,
    }, {
        name: "Wd2",
        controller: Ctrl2,
    }];

    $scope.test = "test";
}
于 2013-07-21T18:13:19.300 回答
0

您可以使用以下指令,该指令将根据名称插入控制器:

var module = angular.module('testApp', []);

module
.directive('dynamicController', ['$controller', function($controller) {
    return {
            restrict: 'A',
            scope: true,
            link: function (scope, element, attrs) {

                var locals = {
                    $scope: scope,
                    $element: element,
                    $attrs: attrs
                };

                element.data('$Controller', $controller(scope.$eval(attrs.dynamicController), locals));                       
            }
        };
    }
])

var module = angular.module('testApp', []);

module
  .directive('dynamicController', ['$controller',
    function($controller) {
      return {
        restrict: 'A',
        scope: true,
        link: function(scope, element, attrs) {

          var locals = {
            $scope: scope,
            $element: element,
            $attrs: attrs
          };

          element.data('$Controller', $controller(scope.$eval(attrs.dynamicController), locals));
        }
      };
    }
  ])

.controller('Ctrl1', ['$scope',
    function($scope) {
      $scope.test = "test 1";
    }
  ])
  .controller('Ctrl2', ['$scope',
    function($scope) {
      $scope.test = "test 2";
    }
  ])
  .controller('ComponentsController', ['$scope',
    function($scope) {
      $scope.components = [{
        name: "Wd1",
        controller: "Ctrl1",
      }, {
        name: "Wd2",
        controller: "Ctrl2",
      }];

      $scope.test = "test";
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>

<div ng-app="testApp">
  <div ng-controller="ComponentsController">
    <div ng-repeat="component in components" dynamic-controller="component.controller">
      <p><span>{{test}}</span>
      </p>
    </div>
  </div>
</div>

于 2015-10-02T08:30:54.493 回答