102

Simple question: How can I set a scope value in html, to be read by my controller?

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

app.controller('MyController', function($scope) {
  console.log($scope.myVar);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app'>
  <div ng-controller="MyController" app-myVar="test">
    {{myVar}}
  </div>
</div>

JSFiddle: http://jsfiddle.net/ncapito/YdQcX/

5
  • You may be better off creating a directive to handle this. A directive would encapsulate: the parameter(s), a controller specific to this directive, and a template for the 'myMap' markup. Commented May 28, 2013 at 16:53
  • Thats actually what I did... just having some issues with accessing $scope.myVar in the directive controller. Why do I have to use a watch in the controller to access the scope variables? Commented May 28, 2013 at 17:02
  • 1
    Maybe you could post your directive? Take a look at "Understanding transclusion and scopes" here docs.angularjs.org/guide/directive You probably need scope: { myVar : '=' } and you would say my-var="foo" when you call it. Note use of hyphen vs. camelCase. Note: foo here is evaluated, if you don't want that use '@' in the scope definition to access the value of the attribute. Commented May 28, 2013 at 19:17
  • 1
    @Nix Can you explain why the value needs to be initialized in the view, rather than in your controller? I assume you already know that's not the conventional way of initializing values (otherwise you wouldn't be asking), and others will be able to give you better answers if they understand your use case better. Commented Mar 14, 2016 at 22:49
  • 1
    @SeantheBean i was young and foolish... ;) i have no clue why i needed to do it. I was probably trying to hack around something. Commented Mar 15, 2016 at 13:54

9 Answers 9

142

ng-init does not work when you are assigning variables inside loop. Use {{myVariable=whatever;""}}

The trailing "" stops the Angular expression being evaluated to any text.

Then you can simply call {{myVariable}} to output your variable value.

I found this very useful when iterating multiple nested arrays and I wanted to keep my current iteration info in one variable instead of querying it multiple times.

Sign up to request clarification or add additional context in comments.

4 Comments

Although this works, it seems hacky. That is, it's generally good practice to use {{}} only for outputting a single variable, not for assigning variables. I'd say stackoverflow.com/a/16799763/814160 is more correct (less JS code in the view).
+1 for @SeantheBean - I have tested this. There seems to be issues with child controllers and the scope of assigning the variable in the markup. The directive works for my purposes and appears to be a solid solution.
This doesn't seem to work in angular2/4 - Bindings cannot contain assignments
@Demodave you should instead set all your controller variables in Typescript code, and use the template only to connect Typescript to HTML. The template should not be assigning variables.
85

ngInit can help to initialize variables.

<div ng-app='app'>
    <div ng-controller="MyController" ng-init="myVar='test'">
        {{myVar}}
    </div>
</div>

jsfiddle example

2 Comments

It should be noted they don't recommend this solution for real apps (but don't really suggest an alternative): docs.angularjs.org/guide/dev_guide.mvc.understanding_model
This worked for me, however, at first the variable was still undefined in the controller. I made a little interval loop: var interval = setInterval(function() { if ($scope.whatever) { // dostuff clearInterval(interval); } }, 10);
19

Create a directive called myVar with

scope : { myVar: '@' }

and call it like this:

<div name="my_map" my-var="Richmond,VA">

Note in particular the camel case reference in the directive to the hyphenated tag name.

For more information see "Understanding Transclusion and Scopes" here:- http://docs.angularjs.org/guide/directive

Here's a Fiddle that shows how you can copy values from attributes to scope variables in various different ways within a directive.

10 Comments

I want to be able to do multiple ones var-nick='my' var-nick2='test'. Unless you can think of a way to implement it with directives I am just going to use ng-init
You can include multiple attributes in the scope, all you need is for one of them to be the name of the directive that you want to execute (or include that directive name too in the html). scope: {varNick: '@', varNick2: '@'}
But its not scalable? I would have to define a directive per variable ?
No, you don't need a directive per variable. Take a look at the fiddle I added to the answer.
Sorry I miss read, your example is perfect, my only change was scope{'@': '@"}.
|
10

You can set values from html like this. I don't think there is a direct solution from angular yet.

 <div style="visibility: hidden;">{{activeTitle='home'}}</div>

1 Comment

Nice hack ... would recommend <div style="display: none"> however.
3

You can use ng-init as shown below

<div class="TotalForm">
  <label>B/W Print Total</label>
  <div ng-init="{{BWCount=(oMachineAccounts|sumByKey:'BWCOUNT')}}">{{BWCount}}</div>
</div>
<div class="TotalForm">
  <label>Color Print Total</label>
  <div ng-init="{{ColorCount=(oMachineAccounts|sumByKey:'COLORCOUNT')}}">{{ColorCount}}</div>
</div>

and then use the local scope variable in other sections:

<div>Total: BW: {{BWCount}}</div>
<div>Total: COLOR: {{ColorCount}}</div>

1 Comment

I like this approach; seems less hacky. One clarification though, ng-init doesn't need the curly braces.
1
$scope.$watch('myVar', function (newValue, oldValue) {
        if (typeof (newValue) !== 'undefined') {
            $scope.someothervar= newValue;
//or get some data
            getData();
        }


    }, true);

Variable initializes after controller so you need to watch over it and when it't initialized the use it.

Comments

1

If you not in a loop, you can use ng-init else you can use

{{var=foo;""}}

the "" alows not display your var

Comments

0

I like the answer but I think it would be better that you create a global scope function that will allow you to set the scope variable needed.

So in the globalController create

$scope.setScopeVariable = function(variable, value){
    $scope[variable] = value;
}

and then in your html file call it

{{setScopeVariable('myVar', 'whatever')}}

This will then allow you to use $scope.myVar in your respective controller

Comments

0

You can use the ng-value directive in a hidden field as below :-

<input type="hidden" ng-value="myScopeVar = someValue"/>

This will set the value of the scope variable (myScopeVar) to "someValue"

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.