source

파라미터를 Angular에 전달할 수 있습니까?JS 컨트롤러가 생성 중입니까?

gigabyte 2022. 9. 17. 09:55
반응형

파라미터를 Angular에 전달할 수 있습니까?JS 컨트롤러가 생성 중입니까?

API와 통신하여 사용자, 이름, 이메일 등의 속성을 업데이트하는 컨트롤러가 있습니다.에게는 「」가 .'id'프로파일 페이지가 표시되었을 때 서버에서 전달됩니다.

는 이 을 Angular에게 .JS API를 사용합니다. 제가 '넘겨보려고 하다.ng-controller §:

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

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

HTML에서

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

서 ''는{% id %}아이디 하지만 오류가 발생합니다.

컨트롤러 생성 시 컨트롤러에 값을 전달하는 올바른 방법은 무엇입니까?

주의:

이 대답은 오래되었다.이것은 원하는 결과를 얻을 수 있는 방법에 대한 개념의 증명일 뿐입니다.다만, 이하의 코멘트에 의하면, 최적인 솔루션은 아닐 수 있습니다.다음 방법을 지원하거나 거부할 수 있는 문서가 없습니다.이 토픽에 대한 자세한 설명은 아래 코멘트를 참조해 주세요.

원답:

, 절대 할 수 요, 라고 했습니다.네, 이 방법은 사용할 수 없습니다.ng-init단순한 초기화 함수.

여기 플런커에 대한 예가 있습니다.

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>

자바스크립트

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)
  };


});

, ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★$attrs컨트롤러 기능에 주입할 수 있으므로 요소에 제공되는 "컨트롤러"를 사용하여 컨트롤러를 초기화할 수 있습니다.

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>

다시 말하지만, 이것이 좋은 생각인지는 모르겠지만, 효과가 있고 또 다른 대안이다.

이것도 효과가 있어요.

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>

뷰에서 구성을 지시하지 마십시오.

Angular에서 템플릿은 설정을 지시하지 않습니다.이 설정은 템플릿파일에서 컨트롤러에 인수를 전달할 때 기본적으로 필요한 것입니다.이것은 미끄러운 경사면이 된다.설정값이 템플릿에 하드코드되어 있는 경우(디렉티브 또는 controller 인수 애틀리뷰트 등), 그 템플릿을 1회 사용 이외에는 다른 용도로 재사용할 수 없습니다.머지않아 템플릿을 재사용하고 싶어질 것입니다.다양한 설정을 사용하여 템플릿을 전처리하여 변수를 주입하거나 방대한 명령어를 사용하여 HTML의 거대한 블록을 뱉어내기 위해 wrapper div 및 인수를 제외한 모든 컨트롤러 HTML을 재사용합니다.소규모 프로젝트에서는 큰 문제가 되지 않습니다.큰 것(각도가 뛰어난 것)은 금방 추해진다.

대안: 모듈

이러한 유형의 설정은 모듈이 처리하도록 설계되어 있습니다.많은 각도 튜토리얼에서 사용자는 애플리케이션 전체를 위한 단일 모듈을 가지고 있지만, 실제로는 시스템이 설계되어 전체 애플리케이션의 작은 부분을 감싸는 많은 작은 모듈을 완전히 지원합니다.컨트롤러, 모듈 등은 개별 파일로 선언되어 재사용 가능한 특정 청크로 함께 결합되는 것이 이상적입니다.어플리케이션이 이렇게 설계되면 컨트롤러의 간단한 인수와 더불어 많은 재사용이 가능합니다.

다음 예에서는 2개의 모듈을 사용하여 동일한 컨트롤러를 재사용하고 있지만 각각 자체 설정값을 가지고 있습니다.됩니다.module.value컨스트럭터 의존성 주입, 재사용 가능한 컨트롤러 코드, 재사용 가능한 컨트롤러 템플릿(컨트롤러 div는 ng-include에 쉽게 포함될 수 있음), HTML을 사용하지 않고 쉽게 유닛 테스트 가능한 시스템, 마지막으로 부품을 꿰매는 수단으로서 재사용 가능한 모듈을 가지고 있기 때문에 이는 각도 방식을 고수합니다.

다음은 예를 제시하겠습니다.

<!-- 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>

jsFiddle을 실제로 사용해 보십시오.

@ 및 제안하는 은 @akonsu Nigel Findlater입니다.은 @akonsu Nigel Findlater 입니다.index.html#/user/:id$routeParams.id이치노

앱:

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

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

자원 서비스

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

컨트롤러

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

리리 then then then then 。elm is 、 [ ]에 따라서는, 할 수 있습니다.id

ifng-init에 물체를 전달하기 위한 것이 아니다.$scope이치노제가 알아낸 건 다음과 같습니다.

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

Javascript:

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>

그러나 이 접근 방식에서는 컨트롤러에 이미 정의된 개체만 수정할 수 있습니다.

당신에게 가장 좋은 해결책은 지시인 것 같습니다.이렇게 하면 컨트롤러를 계속 사용할 수 있지만 컨트롤러의 커스텀 속성을 정의할 수 있습니다.

래핑 범위의 변수에 액세스해야 하는 경우 다음과 같이 하십시오.

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>

래핑 범위의 변수에 액세스할 필요가 없는 경우 다음과 같이 하십시오.

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>

$routeProvider에서 전달되는 변수가 유용하다는 것을 발견했습니다.

예를 들어 여러 화면에 대해 하나의 MyController를 사용하여 매우 중요한 변수 "mySuperConstant"를 내부에 전달합니다.

다음과 같은 간단한 구조를 사용합니다.

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);

    }

예를 들어 의 경로를 설정할 때 이 작업을 수행할 수 있습니다.

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

그리고 나중에 그것을 로 사용하세요.

(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;
  }
})();

이 시점에서 송신한 루트를 설정합니다.아이템나중에 $routeParams에서 입력하고 검색합니다.

컨트롤러에 $routeParams를 삽입하고 여기에 설명된 URL 파라미터를 사용함으로써 파라미터를 컨트롤러에 전달하는 다른 방법이 있습니다.AngularJs에서 쿼리 파라미터를 읽는 가장 간결한 방법은 무엇입니까?

이 질문은 오래되었지만, 저는 제 요구에 맞는 답을 찾기 위해 오랫동안 고민했고 쉽게 찾을 수 없었습니다.저는 이 질문이 처음 제기된 이후 각도가 기능을 추가했기 때문에 다음 솔루션이 현재 받아들여지고 있는 솔루션보다 훨씬 낫다고 생각합니다.

간단히 말하면 Module.value 메서드를 사용하면 데이터를 컨트롤러 컨스트럭터에 전달할 수 있습니다.

여기 내 플런커

모델 개체를 만든 다음 모듈 컨트롤러와 연결하여 '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>

그런 다음 컨트롤러의 생성자는 동일한 식별자 '모델'을 가진 매개 변수를 받아들입니다. 이 매개 변수에 액세스할 수 있습니다.

컨트롤러

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

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

주의:

부트스트래핑의 수동 초기화를 사용하고 있기 때문에 모델을 angular로 보내기 전에 초기화할 수 있습니다.이는 기존 코드와 훨씬 더 잘 어울립니다. 관련 데이터를 설정하고 필요할 때 앱의 각진 부분 집합을 컴파일하는 것을 기다릴 수 있습니다.

plunker에 처음에 javascript에서 정의되어 angular로 전달된 모델 객체의 값을 알려주는 버튼을 추가했습니다. 단지 angular가 모델 객체를 복사하고 복사 작업을 하는 것이 아니라 실제로 참조하고 있는지 확인하기 위해서입니다.

이 행의 경우:

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

MyController 오브젝트를 인라인 함수로 선언하지 않고 Module.controller 함수로 전달합니다.이를 통해 컨트롤러 객체를 훨씬 명확하게 정의할 수 있다고 생각합니다만, Angular 문서에서는 인라인 방식으로 하는 경향이 있기 때문에 명확하게 설명할 수 있다고 생각했습니다.

"controller as" 구문을 사용하여 "$scope" 변수가 아닌 MyController의 "this" 속성에 값을 할당합니다.$scope를 사용해도 정상적으로 동작합니다.컨트롤러 할당은 다음과 같습니다.

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

컨트롤러 컨스트럭터의 시그니처는 다음과 같습니다.

function MyController ($scope, model) {

어떤 이유로든 이 모델을 두 번째 모듈의 값으로 부가할 수 있습니다.이 값은 프라이머리 모듈에 종속되어 부가됩니다.

나는 그의 솔루션이 현재 받아들여지고 있는 솔루션보다 훨씬 낫다고 생각한다. 왜냐하면

  1. 컨트롤러에 전달된 모델은 실제로 javascript 개체이며 평가되는 문자열이 아닙니다.이는 객체에 대한 진정한 참조이며 변경사항은 이 모델 객체에 대한 다른 참조에 영향을 미칩니다.
  2. Angular는 ng-init를 사용하는 것은 오용이며, 이 솔루션에서는 그렇지 않다고 말합니다.

지금까지 본 대부분의 예에서 Angular가 작동하는 방식은 컨트롤러가 모델의 데이터를 정의하는 방식인데, 이는 전혀 이해가 가지 않으며 모델과 컨트롤러 사이에 아무런 구분이 없기 때문에 MVC처럼 보이지 않습니다.이 솔루션을 사용하면 완전히 다른 모델 객체를 컨트롤러에 전달할 수 있습니다.또한 ng-include 디렉티브를 사용하면 모든 각도 html을 별도의 파일에 넣을 수 있으며 모델 뷰와 컨트롤러를 별도의 모듈러로 완전히 분리할 수 있습니다.

angular-ui-module을 사용하는 경우 올바른 솔루션은 다음과 같습니다.https://github.com/angular-ui/ui-router/wiki#resolve

기본적으로 컨트롤러가 인스턴스화되기 전에 일련의 의존관계를 "해결"할 것을 선언합니다.각 "상태"에 대한 종속성을 선언할 수 있습니다.이러한 의존관계는 컨트롤러의 "컨스트럭터"로 전달됩니다.

이를 위한 한 가지 방법은 공공 데이터 멤버인 이러한 논쟁의 '용기'로 사용할 수 있는 별도의 서비스를 갖는 것입니다.

이것은 @Michael Tiller의 훌륭한 답변을 확장한 것입니다.그의 답변은 view에서 변수를 초기화하는 데 사용됩니다.$attrs오브젝트를 컨트롤러에 넣습니다.는 같은 가 '에서 되었을 때 합니다.$routeProvider츠요시 에러가 발생합니다.Unknown provider : $attrsProvider$attrs뷰가 컴파일된 경우에만 주입할 수 있습니다.를 foo(foo)로입니다.$routeParams루트에서 컨트롤러를 초기화할 때$attrs컨트롤러를 초기화할 때 사용합니다.제 해결책은 이렇습니다.

발신기지 루트

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

은, 「URL」 를 합니다.'/mypage/bar' foo는 되며 foo url param을 $injector '블랭크 오브젝트'를 지정합니다.$attrs주입기 오류는 없습니다.

뷰에서

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

</div>

이것으로 컨트롤러는

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'

});

특정 사용 사례에 대한 솔루션 중 마음에 드는 것이 없었기 때문에 여기에 없는 것을 투고하기로 했습니다.

단순히 ng-repeat 루프 내에서 명령어와 같은 컨트롤러를 사용하고 싶을 뿐입니다.

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

「」, 「」에 하려면 , 「」, 「」, 「」에 액세스 합니다.objParameter 언제든지하기 위해 은 $하고 "DirectiveLikeController"를 호출하는 것 입니다.$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); 
});

볼 수 있는 인 단점은 부모 이 '''로 되어 있다는 을 알아야 입니다.objParameter.

아니, 그건 불가능해.ng-init을 hack http://docs.angularjs.org/api/ng.directive:ngInit으로 사용하시면 될 것 같습니다.

이 솔루션(Marcin Wyszynski의 제안에 따라)은 컨트롤러에 값을 전달하고 싶지만 html(ng-init이 필요한 것 같음)에서 컨트롤러를 명시적으로 선언하지 않습니다.예를 들어 템플릿을 ng-view로 렌더링하고 ro를 통해 대응하는 루트에 대해 각 컨트롤러를 선언하는 경우입니다.ute Provider.

JS

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>

이 솔루션에서 Current User는 모든 컨트롤러에 삽입할 수 있는 서비스이며 .name 속성을 사용할 수 있습니다.

두 가지 주의:

  • 컨트롤러가 로드된 후에 .name이 설정되기 때문에 회피책으로 컨트롤러의 스코프에서 사용자 이름을 렌더링하기 전에 짧은 타임아웃이 발생합니다.서비스에 .name이 설정될 때까지 기다리는 깔끔한 방법이 있나요?

  • 이것은 현재 사용자를 Angular 앱으로 끌어들이는 매우 쉬운 방법처럼 느껴지며 Angular 외부에서 모든 인증을 유지할 수 있습니다.로그인하지 않은 사용자가 Angular 앱이 부트스트랩되어 있는 html에 접속하는 것을 방지하기 위해 before_filter를 사용할 수 있습니다.또한 이 html 내에서 로그인한 사용자의 이름과 사용자의 ID를 Angular 앱에서 http 요청을 통해 상호 작용하고 싶을 경우 보간할 수 있습니다.로그인하지 않은 사용자가 기본 '게스트 사용자'와 함께 Angular App을 사용하도록 허용할 수 있습니다.왜 이 방법이 나쁜지에 대한 조언은 어떤 것이든 환영할 것입니다. - 너무 쉽게 느껴져서 분별력이 없어집니다!)

언급URL : https://stackoverflow.com/questions/14523679/can-you-pass-parameters-to-an-angularjs-controller-on-creation

반응형