Bạn có thể truyền tham số cho bộ điều khiển AngularJS khi tạo không?


278

Tôi có một bộ điều khiển chịu trách nhiệm liên lạc với API để cập nhật các thuộc tính của người dùng, tên, email, v.v. Mỗi người dùng có một 'id'bộ được truyền từ máy chủ khi xem trang hồ sơ.

Tôi muốn chuyển giá trị này cho bộ điều khiển AngularJS để nó biết điểm nhập API là gì đối với người dùng hiện tại. Tôi đã thử chuyển giá trị vào ng-controller. Ví dụ:

function UserCtrl(id, $scope, $filter) {

$scope.connection = $resource('api.com/user/' + id)

và trong HTML

<body ng-controller="UserCtrl({% id %})">

trong đó {% id %}in id được gửi từ máy chủ. nhưng tôi nhận được lỗi.

Cách chính xác để chuyển một giá trị vào bộ điều khiển khi tạo ra nó là gì?


6
nếu bạn có id là một phần của url thì bạn chỉ cần đọc url
akonsu

Tôi đã có vấn đề rất giống nhau và tôi đã giải quyết nó như tôi đã đăng trong câu trả lời của mình. Đôi khi sử dụng các thư viện, chúng tôi bỏ qua khái niệm cơ bản đơn giản về lệnh gọi hàm JavaScript.
Jigar Patel

@nickponline Sau 21+ bạn vẫn nghĩ rằng điều đó là không thể?
om471987

Câu trả lời:


362

Ghi chú:

Câu trả lời này là cũ. Đây chỉ là một bằng chứng về khái niệm về cách đạt được kết quả mong muốn. Tuy nhiên, nó có thể không phải là giải pháp tốt nhất theo một số bình luận dưới đây. Tôi không có bất kỳ tài liệu nào để hỗ trợ hoặc từ chối phương pháp sau. Vui lòng tham khảo một số ý kiến ​​dưới đây để thảo luận thêm về chủ đề này.

Câu trả lời gốc:

Tôi đã trả lời điều này cho Có, bạn hoàn toàn có thể làm như vậy bằng cách sử dụng ng-initvà một hàm init đơn giản.

Dưới đây là ví dụ về nó trên plunker

HTML

<!DOCTYPE html>
<html ng-app="angularjs-starter">
  <head lang="en">
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="app.js"></script>
  </head>  
  <body ng-controller="MainCtrl" ng-init="init('James Bond','007')">
    <h1>I am  {{name}} {{id}}</h1>
  </body>
</html>

JavaScript

var app = angular.module('angularjs-starter', []);

app.controller('MainCtrl', function($scope) {

  $scope.init = function(name, id)
  {
    //This function is sort of private constructor for controller
    $scope.id = id;
    $scope.name = name; 
    //Based on passed argument you can make a call to resource
    //and initialize more objects
    //$resource.getMeBond(007)
  };


});

5
Cảm ơn vì điều này - đã cứu tôi rất nhiều điều khó khăn, và nó hoạt động hoàn hảo cho tình huống của tôi. Tôi đã phải khởi tạo bộ điều khiển của mình với ID đối tượng và điều này hoàn toàn đúng.
Masonoise

26
Từ các tài liệu :The only appropriate use of ngInit for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
Serge Goliney

8
Câu trả lời cho thấy rõ rằng đề xuất của tài liệu chống lại phương pháp này, nhưng ai đó có thể chỉ cho tôi nơi tài liệu cung cấp giải pháp chính thức không?
Michael Pell

53
Vâng, tôi nghĩ rằng các tài liệu rất kém khi chỉ đề xuất chống lại phương pháp này mà không đưa ra lý do tại sao. Tôi nghĩ rằng đây là một cách tiếp cận tuyệt vời. Nếu các tác giả khung không muốn sử dụng khung theo cách "sai" đối với họ, thì họ không nên sử dụng theo cách "sai" đó ... và cung cấp hướng dẫn về " đúng cách!
Shawn de Wet

2
một lời cảnh báo - nếu bạn đang cố gắng liên kết với một giá trị phạm vi hoặc thực sự làm bất cứ điều gì mong đợi giá trị đó xuất hiện trong chức năng của bộ điều khiển, thì nó đã chạy chức năng của bộ điều khiển trước khi ng-initxảy ra - xem plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = xem trước
drzaus

143

Tôi rất muộn với điều này và tôi không biết liệu đây có phải là một ý tưởng hay không, nhưng bạn có thể đưa vào phần $attrstiêm trong hàm điều khiển cho phép bộ điều khiển được khởi tạo bằng cách sử dụng "đối số" được cung cấp trên một phần tử, ví dụ

app.controller('modelController', function($scope, $attrs) {
    if (!$attrs.model) throw new Error("No model for modelController");

    // Initialize $scope using the value of the model attribute, e.g.,
    $scope.url = "http://example.com/fetch?model="+$attrs.model;
})

<div ng-controller="modelController" model="foobar">
  <a href="{{url}}">Click here</a>
</div>

Một lần nữa, không có ý tưởng nếu đây là một ý tưởng tốt, nhưng nó dường như hoạt động và là một thay thế khác.


3
Làm thế nào tôi có thể vượt qua một đối tượng bằng cách sử dụng phương pháp này? var obj = {a: 1, b: 2};
Neil

3
Đây là một giải pháp rất hợp lý cho vấn đề sản xuất một ứng dụng lai.
siêu sáng

2
@Neil: bạn phải xâu chuỗi đối tượng json của bạn và sau đó phân tích nó bên trong bộ điều khiển. Không phải là giải pháp đẹp hơn, nhưng nó có thể hoạt động. Giải pháp của Michael rất phù hợp với các tham số giống như chuỗi ...
M'sieur Toph '

1
điều này thực sự đáng tin cậy hơn so với việc sử dụng ng-init- nếu bạn đang cố liên kết với một giá trị phạm vi, thì nó đã chạy chức năng của bộ điều khiển trước khi ng-initxảy ra - xem plnkr.co/edit/donCm6FRBSX9oENXh9WJ?p=preview
drzaus

2
Tôi không nhận được tất cả các phát minh lại bánh xe bằng các chỉ thị, v.v. Nếu bạn có một bộ điều khiển mà bạn muốn sử dụng trong nhiều chế độ xem với một vài tham số khởi tạo khác nhau, đây là giải pháp dễ dàng và đáng tin cậy nhất.
Eric H.

39

Điều này cũng hoạt động.

Javascript:

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

app.controller('MainCtrl', function($scope, name, id) {
    $scope.id = id;
    $scope.name = name;
    // and more init
});

Html:

<!DOCTYPE html>
<html ng-app="angularApp">
  <head lang="en">
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="app.js"></script>
    <script>
       app.value("name", "James").value("id", "007");
    </script>
  </head>
  <body ng-controller="MainCtrl">
    <h1>I am  {{name}} {{id}}</h1>
  </body>
</html>

3
Đây là một giải pháp tốt hoạt động với cơ chế tiêm xây dựng hiện có. Về bản chất, bạn đang tạo hai dịch vụ đơn giản gọi là 'tên' và 'id'. Người tiêm sẽ chăm sóc khớp chúng theo tên trong quá trình xây dựng. Xem: phần Công thức giá trị của docs.angularjs.org/guide/providers
Todd

1
Đẹp. Lưu ý điều này cũng hoạt động với các đối tượng, không chỉ các kiểu nguyên thủy như chuỗi.
jbustamovej

Tôi thích giải pháp này tốt hơn. Tôi đã có thể mô đun hóa các mã trùng lặp của mình thông qua việc truyền tham số. Chúc mừng!
agentpx

Điều này có vẻ như là cách thành ngữ nhất, nhưng tôi không chắc nó được đề xuất bởi đội ngũ góc cạnh
VinGarcia

Điều này về cơ bản có thiết lập các cặp khóa / giá trị toàn cầu không? Chúng có thể được đặt trong phạm vi của một bộ điều khiển nhất định để nó chỉ được chọn trên các bộ điều khiển con bên dưới bộ điều khiển chính không? Nếu không, có vẻ như điều này thực sự không khác nhiều so với việc chỉ đặt một biến Javascript toàn cầu thông thường ở cấp cửa sổ.
jpierson

16

Chế độ xem không nên ra lệnh cấu hình

Trong Angular, mẫu không bao giờ ra lệnh cấu hình, vốn dĩ là thứ mà mọi người mong muốn khi họ muốn truyền đối số cho bộ điều khiển từ tệp mẫu. Điều này trở thành một dốc trơn trượt. Nếu cài đặt cấu hình được mã hóa cứng trong các mẫu (chẳng hạn như thuộc tính đối số chỉ thị hoặc bộ điều khiển), bạn không còn có thể sử dụng lại mẫu đó cho bất cứ điều gì ngoại trừ việc sử dụng một lần. Bạn sẽ sớm muốn sử dụng lại mẫu đó, nhưng với cấu hình khác và bây giờ để làm như vậy, bạn sẽ xử lý trước các mẫu để tiêm biến trước khi nó được chuyển sang góc cạnh hoặc sử dụng các lệnh lớn để phun ra khổng lồ các khối HTML để bạn sử dụng lại tất cả HTML của bộ điều khiển ngoại trừ div của trình bao bọc và các đối số của nó. Đối với các dự án nhỏ, đó không phải là vấn đề lớn. Đối với một cái gì đó lớn (những gì góc cạnh vượt trội), nó trở nên xấu xí nhanh chóng.

Thay thế: Mô-đun

Kiểu cấu hình này là những gì mô-đun được thiết kế để xử lý. Trong nhiều hướng dẫn góc cạnh, mọi người có một mô-đun duy nhất cho toàn bộ ứng dụng của họ, nhưng thực sự hệ thống được thiết kế và hỗ trợ đầy đủ nhiều mô-đun nhỏ, mỗi mô-đun bao gồm các phần nhỏ của tổng ứng dụng. Lý tưởng nhất, bộ điều khiển, mô-đun, vv sẽ được khai báo trong các tệp riêng biệt và được ghép lại với nhau trong các khối có thể sử dụng lại cụ thể. Khi ứng dụng của bạn được thiết kế theo cách này, bạn sẽ có được rất nhiều lần sử dụng lại ngoài các đối số điều khiển dễ dàng.

Ví dụ dưới đây có 2 mô-đun, sử dụng lại cùng một bộ điều khiển, nhưng mỗi mô-đun có cài đặt cấu hình riêng. Các cài đặt cấu hình đó được truyền qua thông qua tiêm phụ thuộc bằng cách sử dụngmodule.value . Điều này tuân thủ cách thức góc cạnh bởi vì chúng tôi có các yếu tố sau: tiêm phụ thuộc hàm tạo, mã điều khiển tái sử dụng, các mẫu điều khiển có thể tái sử dụng (div bộ điều khiển có thể dễ dàng được bao gồm với ng-bao gồm), hệ thống có thể kiểm tra đơn vị dễ dàng mà không cần HTML và cuối cùng có thể sử dụng lại mô-đun như là phương tiện để khâu các mảnh lại với nhau.

Đây là một ví dụ:

<!-- index.html -->
<div id="module1">
    <div ng-controller="MyCtrl">
        <div>{{foo}}</div>
    </div>
</div>
<div id="module2">
    <div ng-controller="MyCtrl">
        <div>{{foo}}</div>
    </div>
</div>
<script>
    // part of this template, or a JS file designed to be used with this template
    angular.element(document).ready(function() {
        angular.bootstrap(document.getElementById("module1"), ["module1"]);
        angular.bootstrap(document.getElementById("module2"), ["module2"]);
    });
</script>

<!-- scripts which will likely in be in their seperate files -->
<script>
    // MyCtrl.js
    var MyCtrl = function($scope, foo) {
    $scope.foo = foo;
    }

    MyCtrl.$inject = ["$scope", "foo"];

    // Module1.js
    var module1 = angular.module('module1', []);
    module1.value("foo", "fooValue1");
    module1.controller("MyCtrl", MyCtrl);

    // Module2.js file
    var module2 = angular.module('module2', []);
    module2.value("foo", "fooValue2");
    module2.controller("MyCtrl", MyCtrl);
</script>

Xem nó trong hành động: jsFiddle .


tôi đã nâng cao, nhưng tôi muốn nói lời cảm ơn vì sự đóng góp của bạn. Câu trả lời này đặt tôi trên một con đường tốt hơn. stackoverflow là tốt nhất khi mọi người chia sẻ các thực tiễn tốt nhất và không chỉ là các đoạn hacky. Điều này thật tuyệt vời: "mẫu không bao giờ ra lệnh cấu hình, vốn dĩ là điều mọi người mong muốn khi họ muốn truyền đối số cho bộ điều khiển từ tệp mẫu". cảm ơn bạn đã có tầm nhìn laser vào trung tâm của vấn đề.
hại

15

Giống như @akonsu và Nigel Findlater gợi ý, bạn có thể đọc các url nơi url là index.html#/user/:idvới $routeParams.idvà sử dụng nó bên trong bộ điều khiển.

ứng dụng của bạn:

var app = angular.module('myApp', [ 'ngResource' ]);

app.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/:type/:id', {templateUrl: 'myView.html', controller: 'myCtrl'});
}]);

dịch vụ tài nguyên

app.factory('MyElements', ['$resource', function($resource) {
     return $resource('url/to/json/:type/:id', { type:'@type', id:'@id' });
}]);

bộ điều khiển

app.controller('MyCtrl', ['$scope', '$routeParams', 'MyElements', function($scope, $routeParams, MyElements) {
    MyElements.get({'type': $routeParams.type, "id": $routeParams.id }, function(elm) {
        $scope.elm = elm;
    })
}]);

sau đó, elmcó thể truy cập trong chế độ xem tùy thuộc vào id.


8

Nếu ng-initkhông phải để truyền các đối tượng vào $scope, bạn luôn có thể viết chỉ thị của riêng bạn. Vì vậy, đây là những gì tôi nhận được:

http://jsfiddle.net/goliney/89bLj/

Javasript:

var app = angular.module('myApp', []);
app.directive('initData', function($parse) {
    return function(scope, element, attrs) {
        //modify scope
        var model = $parse(attrs.initData);
        model(scope);
    };
});

function Ctrl1($scope) {
    //should be defined
    $scope.inputdata = {foo:"east", bar:"west"};
}

Html:

<div ng-controller="Ctrl1">
    <div init-data="inputdata.foo=123; inputdata.bar=321"></div>
</div>

Nhưng cách tiếp cận của tôi chỉ có thể sửa đổi các đối tượng, đã được xác định tại bộ điều khiển.


Để tham khảo, nó hoạt động rất tốt nhưng trên phiên bản góc cạnh hiện tại, nó là $ attrs (so với attrs)
Dinis Cruz

8

Có vẻ như giải pháp tốt nhất cho bạn thực sự là một chỉ thị. Điều này cho phép bạn vẫn có bộ điều khiển của mình, nhưng xác định các thuộc tính tùy chỉnh cho nó.

Sử dụng điều này nếu bạn cần truy cập vào các biến trong phạm vi gói:

angular.module('myModule').directive('user', function ($filter) {
  return {
    link: function (scope, element, attrs) {
      $scope.connection = $resource('api.com/user/' + attrs.userId);
    }
  };
});

<user user-id="{% id %}"></user>

Sử dụng điều này nếu bạn không cần quyền truy cập vào các biến trong phạm vi gói:

angular.module('myModule').directive('user', function ($filter) {
  return {
    scope: {
      userId: '@'
    },
    link: function (scope, element, attrs) {
      $scope.connection = $resource('api.com/user/' + scope.userId);
    }
  };
});

<user user-id="{% id %}"></user>

7

Tôi tìm thấy việc chuyển các biến từ $ routeProvider hữu ích.

Ví dụ: bạn sử dụng một bộ điều khiển MyContoder cho nhiều màn hình, chuyển một số biến rất quan trọng "mySuperConstant" bên trong.

Sử dụng cấu trúc đơn giản đó:

Router:

$routeProvider
            .when('/this-page', {
                templateUrl: 'common.html',
                controller: MyController,
                mySuperConstant: "123"
            })
            .when('/that-page', {
                templateUrl: 'common.html',
                controller: MyController,
                mySuperConstant: "456"
            })
            .when('/another-page', {
                templateUrl: 'common.html',
                controller: MyController,
                mySuperConstant: "789"
            })

MyController:

    MyController: function ($scope, $route) {
        var mySuperConstant: $route.current.mySuperConstant;
        alert(mySuperConstant);

    }

6

Bạn có thể làm điều đó khi thiết lập các tuyến đường cho ví dụ

 .when('/newitem/:itemType', {
            templateUrl: 'scripts/components/items/newEditItem.html',
            controller: 'NewEditItemController as vm',
            resolve: {
              isEditMode: function () {
                return true;
              }
            },
        })

Và sau này sử dụng nó như là

(function () {
  'use strict';

  angular
    .module('myApp')
    .controller('NewEditItemController', NewEditItemController);

  NewEditItemController.$inject = ['$http','isEditMode',$routeParams,];

  function NewEditItemController($http, isEditMode, $routeParams) {
    /* jshint validthis:true */

    var vm = this;
    vm.isEditMode = isEditMode;
    vm.itemType = $routeParams.itemType;
  }
})();

Vì vậy, ở đây khi chúng tôi thiết lập tuyến đường chúng tôi đã gửi: itemType và truy xuất lại sau từ $ routeParams.



3

Câu hỏi này đã cũ nhưng tôi đã đấu tranh trong một thời gian dài để cố gắng có được câu trả lời cho vấn đề này có thể đáp ứng nhu cầu của tôi và không dễ dàng tìm thấy nó. Tôi tin rằng giải pháp sau đây của tôi tốt hơn nhiều so với giải pháp hiện đang được chấp nhận, có lẽ vì góc cạnh đã thêm chức năng vì câu hỏi này ban đầu được đặt ra.

Câu trả lời ngắn, sử dụng phương thức Module.value cho phép bạn truyền dữ liệu vào hàm tạo của bộ điều khiển.

Xem plunker của tôi ở đây

Tôi tạo một đối tượng mô hình, sau đó liên kết nó với bộ điều khiển của mô-đun, tham chiếu nó với tên 'model'

HTML / JS

  <html>
  <head>
    <script>
      var model = {"id": 1, "name":"foo"};

      $(document).ready(function(){
        var module = angular.module('myApp', []);
        module.value('model', model);
        module.controller('MyController', ['model', MyController]);
        angular.bootstrap(document, ['myApp']);
      });

      function confirmModelEdited() {
        alert("model name: " + model.name + "\nmodel id: " + model.id);
      }
    </script>

  </head>
  <body >
      <div ng-controller="MyController as controller">
        id: {{controller.model.id}} <br>
        name: <input ng-model="controller.model.name"/>{{controller.model.name}}
        <br><button ng-click="controller.incrementId()">increment ID</button>
        <br><button onclick="confirmModelEdited()">confirm model was edited</button>
    </div>
  </body>

</html>

Sau đó, hàm tạo trong bộ điều khiển của tôi chấp nhận một tham số có cùng mô hình 'mô hình' mà nó có thể truy cập.

Bộ điều khiển

function MyController (model) {
  this.model = model;
}

MyController.prototype.incrementId = function() {
  this.model.id = this.model.id + 1;
}

Ghi chú:

Tôi đang sử dụng khởi tạo thủ công bootstrapping , cho phép tôi khởi tạo mô hình của mình trước khi gửi nó tới góc. Điều này chơi độc đáo hơn nhiều với mã hiện có, vì bạn có thể chờ đợi để thiết lập dữ liệu liên quan của mình và chỉ biên dịch tập hợp con góc của ứng dụng theo yêu cầu khi bạn muốn.

Trong plunker tôi đã thêm một nút để cảnh báo các giá trị của đối tượng mô hình ban đầu được xác định trong javascript và được chuyển sang góc, chỉ để xác nhận rằng angular thực sự tham chiếu đến đối tượng mô hình, thay vì sao chép nó và làm việc với một bản sao.

Trên dòng này:

module.controller('MyController', ['model', MyController]);

Tôi chuyển đối tượng MyContoder vào hàm Module.contler, thay vì khai báo là một hàm nội tuyến. Tôi nghĩ rằng điều này cho phép chúng tôi xác định rõ hơn đối tượng điều khiển của mình, nhưng tài liệu Angular có xu hướng thực hiện nội tuyến nên tôi nghĩ rằng nó mang lại sự rõ ràng.

Tôi đang sử dụng cú pháp "trình điều khiển như" và gán các giá trị cho thuộc tính "this" của MyContoder, thay vì sử dụng biến "$ scope". Tôi tin rằng điều này cũng sẽ hoạt động tốt khi sử dụng $ scope, việc gán bộ điều khiển sau đó sẽ trông giống như thế này:

module.controller('MyController', ['$scope', 'model', MyController]);

và trình xây dựng bộ điều khiển sẽ có một chữ ký như thế này:

function MyController ($scope, model) {

Nếu vì bất kỳ lý do gì bạn muốn, bạn cũng có thể đính kèm mô hình này như một giá trị của mô-đun thứ hai, sau đó bạn đính kèm như một phụ thuộc vào mô-đun chính của mình.

Tôi tin rằng giải pháp của anh ấy tốt hơn nhiều so với giải pháp hiện đang được chấp nhận bởi vì

  1. Mô hình được truyền cho bộ điều khiển thực sự là một đối tượng javascript, không phải là một chuỗi được đánh giá. Nó là một tham chiếu thực sự cho đối tượng và thay đổi đối với nó ảnh hưởng đến các tham chiếu khác đến đối tượng mô hình này.
  2. Angular nói rằng việc sử dụng ng-init của câu trả lời được chấp nhận là sử dụng sai, điều mà giải pháp này không làm được.

Cách Angular dường như hoạt động trong hầu hết các ví dụ khác mà tôi đã thấy có bộ điều khiển xác định dữ liệu của mô hình, điều này không bao giờ có ý nghĩa với tôi, không có sự tách biệt giữa mô hình và bộ điều khiển, điều đó thực sự không giống MVC với tôi. Giải pháp này cho phép bạn thực sự có một đối tượng mô hình hoàn toàn riêng biệt mà bạn chuyển vào bộ điều khiển. Cũng cần lưu ý, nếu bạn sử dụng lệnh ng-include, bạn có thể đặt tất cả html góc của bạn vào một tệp riêng biệt, tách biệt hoàn toàn chế độ xem mô hình và bộ điều khiển của bạn thành các phần mô-đun riêng biệt.


2

Nếu sử dụng angular-ui-router, thì đây là giải pháp chính xác: https://github.com/angular-ui/ui-router/wiki#resolve

Về cơ bản, bạn khai báo một tập hợp các phụ thuộc để "giải quyết" trước khi bộ điều khiển được khởi tạo. Bạn có thể khai báo các phụ thuộc cho từng "trạng thái" của bạn. Những phụ thuộc này sau đó được chuyển vào "hàm tạo" của bộ điều khiển.


1

Một cách để làm điều đó là có một dịch vụ riêng biệt có thể được sử dụng như một 'tàu' cho những đối số mà họ là thành viên dữ liệu công khai.


Câu trả lời hay nhất, IMO. Tôi hiện cũng sử dụng lưu trữ trình duyệt trong một số trường hợp cho những người dùng dám nhấn F5, vì vậy trạng thái này được duy trì.
túc xá

1

Tôi không thực sự thích bất kỳ giải pháp nào ở đây cho trường hợp sử dụng cụ thể của mình, vì vậy tôi đoán rằng tôi đã đăng những gì tôi đã làm vì tôi không thấy nó ở đây.

Tôi chỉ đơn giản muốn sử dụng một bộ điều khiển giống như một lệnh, trong vòng lặp lặp lại:

<div ng-repeat="objParameter in [{id:'a'},{id:'b'},{id:'c'}]">
  <div ng-controller="DirectiveLikeController as ctrl"></div>
</div>

Bây giờ, để truy cập objParametervào việc tạo trong mỗi DirectiveLikeContoder (hoặc để có được objParameter cập nhật bất cứ lúc nào), tất cả những gì tôi cần làm là tiêm $ scope và gọi $scope.$eval('objParameter'):

var app = angular.module('myapp', []);
app.controller('DirectiveLikeController',['$scope'], function($scope) {
   //print 'a' for the 1st instance, 'b' for the 2nd instance, and 'c' for the 3rd.
   console.log($scope.$eval('objParameter').id); 
});

Nhược điểm thực sự duy nhất mà tôi thấy là nó yêu cầu bộ điều khiển cha phải biết rằng tham số được đặt tên objParameter.


0

Không, no không thể. Tôi nghĩ bạn có thể sử dụng ng-init như hack http://docs.angularjs.org/api/ng.directive:ngInit .


4
Tôi cầu xin khác nhau nhưng bạn có thể thực hiện điều này bằng cách sử dụng ng-init và sử dụng một phiên bản init.
Jigar Patel

một lời cảnh báo - nếu bạn đang cố gắng liên kết với một giá trị phạm vi hoặc thực sự làm bất cứ điều gì mong đợi giá trị đó xuất hiện trong chức năng của bộ điều khiển, thì nó đã chạy chức năng của bộ điều khiển trước khi ng-initxảy ra - xem plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = xem trước
drzaus

Vâng, nó là có thể. Ít nhất, bạn sẽ sử dụng dữ liệu hoặc bất cứ điều gì. Nhưng nó chắc chắn có thể.
Juan

0

Đây là một giải pháp (dựa trên đề xuất của Marcin Wyszynski) hoạt động khi bạn muốn chuyển một giá trị vào bộ điều khiển của mình nhưng bạn không khai báo rõ ràng bộ điều khiển trong html của mình (ví dụ như ng-init yêu cầu) - ví dụ: bạn đang hiển thị các mẫu của mình với ng-view và khai báo từng bộ điều khiển cho tuyến tương ứng thông qua routeProvider.

Mã não

messageboard.directive('currentuser', ['CurrentUser', function(CurrentUser) {
  return function(scope, element, attrs) {
    CurrentUser.name = attrs.name;
  };
}]);

html

<div ng-app="app">
  <div class="view-container">
    <div ng-view currentuser name="testusername" class="view-frame animate-view"></div>
  </div>
</div>

Trong giải pháp này, CurrentUser là một dịch vụ có thể được đưa vào bất kỳ bộ điều khiển nào, với thuộc tính .name có sẵn.

Hai lưu ý:

  • một vấn đề tôi gặp phải là .name được đặt sau khi bộ điều khiển tải, do đó, một cách giải quyết tôi có thời gian chờ ngắn trước khi hiển thị tên người dùng trên phạm vi của bộ điều khiển. Có cách chờ đợi gọn gàng cho đến khi .name đã được đặt trên dịch vụ không?

  • cảm giác này giống như một cách rất dễ dàng để đưa người dùng hiện tại vào Ứng dụng Angular của bạn với tất cả xác thực được giữ bên ngoài Angular. Bạn có thể có một before_filter để ngăn người dùng không đăng nhập vào html nơi ứng dụng Angular của bạn được khởi động và trong html đó bạn chỉ có thể nội suy tên người dùng đã đăng nhập và thậm chí ID của họ nếu bạn muốn tương tác với các chi tiết của người dùng thông qua các yêu cầu http từ ứng dụng Angular của bạn. Bạn có thể cho phép người dùng chưa đăng nhập sử dụng Ứng dụng Angular với 'người dùng khách' mặc định. Bất kỳ lời khuyên nào về lý do tại sao phương pháp này sẽ không được hoan nghênh - cảm thấy quá dễ để có thể cảm nhận được!)


0

Đây là bản mở rộng của câu trả lời xuất sắc của @Michael Tiller's . Câu trả lời của ông hoạt động để khởi tạo các biến từ chế độ xem bằng cách đưa $attrsđối tượng vào bộ điều khiển. Sự cố xảy ra nếu cùng một bộ điều khiển được gọi từ $routeProviderkhi bạn điều hướng bằng cách định tuyến. Sau đó, bạn nhận được lỗi kim phun Unknown provider : $attrsProvider$attrschỉ có sẵn để tiêm khi chế độ xem được biên dịch. Giải pháp là truyền biến (foo) qua $routeParamskhi khởi tạo bộ điều khiển từ tuyến và bởi$attrs khi khởi tạo bộ điều khiển từ chế độ xem. Đây là giải pháp của tôi.

Từ tuyến

$routeProvider.
        when('/mypage/:foo', {
            templateUrl: 'templates/mypage.html',
            controller: 'MyPageController',
            caseInsensitiveMatch: true,
            resolve: {
                $attrs: function () {
                    return {};
                }
            }
        });

Điều này xử lý một url như '/mypage/bar'. Như bạn có thể thấy foo được truyền bởi url param và chúng tôi cung cấp $injectorvới một đối tượng trống $attrsđể không có lỗi trình tiêm.

Từ quan điểm

<div ng-controller="MyPageController" data-foo="bar">

</div>

Bây giờ bộ điều khiển

var app = angular.module('myapp', []);
app.controller('MyPageController',['$scope', '$attrs', '$routeParams'], function($scope, $attrs, $routeParams) {
   //now you can initialize foo. If $attrs contains foo, it's been initialized from view
   //else find it from $routeParams
   var foo = $attrs.foo? $attrs.foo : $routeParams.foo;
   console.log(foo); //prints 'bar'

});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.