AngularJS: Why is ng-click not setting the variable as the value obtained from ng-repeat?

I am trying to give an application a way to set a font for a piece of text based on a list of fonts from Google Fonts.

Here's what I have:

<ul ng-init='headerFont="mono"'>
  <li ng-repeat='font in fonts' style='font-family: {{font}};' ng-click='headerFont = font'>{{font}}
  </li>
</ul>

      

and then later:

<h1 style='font-family: {{headerFont}};'>Header</h1>

      

and in the controller in my js file:

$scope.fonts = [...an array of font names...]

      

Originally, instead of ng-repeat

on, <li>

I used:

<select ng-model='headerFont' style='font-family: {{headerFont}};'>
  <option ng-repeat='font in fonts' style='font-family:{{font}};'>{{font}}
  </option>
</select>

      

And it worked the way I wanted it to. But I wanted to try using a scrollable list instead of a dropdown menu, because the menu <select>

in mobile browsers does not support changing the fonts of individual options, and it is important for me that the fonts can be previewed before Selection. I figured I could just use ng-click

to set the value headerFont

, but it doesn't do anything (no error appears in the console or whatever. It's just that nothing happens.) Does anyone know why?

+3


source to share


2 answers


The problem is that ngRepeat creates a child scope for each iteration, so ngClick actually changes the local child variable headerFont

.

One possible solution is to explicitly specify the parent scope:



var app = angular.module('demo', []);
app.controller('demoController', function($scope) {
    $scope.fonts = ['Arial', 'Times New Roman', 'Verdana', 'mono'];
})
      

<script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>

<div ng-app="demo" ng-controller="demoController">
    <h1 style='font-family: {{headerFont}};'>Header</h1>

    <ul ng-init='headerFont="mono"'>
        <li ng-repeat='font in fonts' style='font-family: {{font}};' ng-click='$parent.headerFont = font'>{{font}}</li>
    </ul>
</div>
      

Run code


+5


source


Everyone ng-repeat

creates a new area. ng-click

changes headerFont

in its area without touching headerFont

the top level.

You can create a dictionary at the top level to prevent the child object from floating:



<ul ng-init="top = {'headerFont':'mono'}">
 <li ng-repeat='font in fonts' 
     style='font-family: {{font}};' 
     ng-click='top.headerFont = font'>
   {{font}} / {{top.headerFont}}
  </li>
</ul>

      

Demo: http://plnkr.co/edit/77zesZsBgYpZUDWciY18?p=preview

+2


source







All Articles