Hello, {{name}} (here is the $rootScope)


hello {{name}}! (here is the $scope of controller)
<body ng-app ng-init="name='World'"> we create here $rootScope with the model: name='World'
<h1>Hello, {name} (here is the $rootScope)</h1>
<div ng-controller='HelloController'>
we create here child scope.
    <input ng-model='name'>
    hello {name}!
Because the child controller is empty (var HelloController = function ($scope) { };), it has no model and sees the "name" of parent scope.

If You type a value in the "Say hello..", You create a model "name=xxx" in the controller scope. And the controller can't see the $rootScope.name any more. So You see than the value $rootScope=="World" over input, and Your tipped value under input field.

Overcome the Problem with different values

The solution involves binding to a property of an object and not directly to a scope's property:
<div ng-controller="HelloController2" ng-init="thing = {name : 'World'}">
    <h1>Hello, {thing.name}</h1>
    <div ng-controller="HelloController3">
        Say hello to: <input type="text" ng-model="thing.name">
        <h2>Hello, {thing.name}!</h2>

Hello, {{thing.name}}

Say hello to:

Hello, {{thing.name}}!