Reputation: 2387
I'm trying to give an app the ability to set the font for portion 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 on:
<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 was using:
<select ng-model='headerFont' style='font-family: {{headerFont}};'>
<option ng-repeat='font in fonts' style='font-family:{{font}};'>{{font}}
</option>
</select>
And that worked exactly like I wanted it to. But I wanted to try using a scrollable list instead of a drop-down menu because the <select>
menu on mobile browsers doesn't support changing fonts of individual options, and it's important to me for the fonts to be able to be previewed before choosing. I figured I could just use ng-click
to set the value of headerFont
, but it doesn't do anything (no errors show up in the console or anything. Just nothing happens.) Does anyone know why?
Upvotes: 3
Views: 4456
Reputation: 34288
Each ng-repeat
creates a new scope. The ng-click
changes the headerFont
in its own scope, without touching the headerFont
on the top level.
You can create dictionary at the top level to prevent the child scope from kicking in:
<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
Upvotes: 2
Reputation: 193271
The problem is that ngRepeat creates child scope for each iteration, so ngClick actually changes local child headerFont
variable.
One possible solution is to explicitly refer parent scope:
var app = angular.module('demo', []);
app.controller('demoController', function($scope) {
$scope.fonts = ['Arial', 'Times New Roman', 'Verdana', 'mono'];
})
<script data-require="[email protected]" 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>
Upvotes: 8