If you look at the Loader library's _ci_load method (which view() calls), around line 639 in the latest version, you'll see this bit of code:
/*
* Extract and cache variables
*
* You can either set variables using the dedicated $this->load_vars()
* function or via the second parameter of this function. We'll merge
* the two types and cache them so that views that are embedded within
* other views can have access to these variables.
*/
if (is_array($_ci_vars))
{
$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
}
extract($this->_ci_cached_vars);
That's why your variables passed to the view are available automatically in nested views.
But your locally declared variable aren't.. because they aren't passed on to the next view() call.
Note that it merges the variables, so technically, you could just pass to your subview the variable that are changed in the top view, the rest will be inherited automatically.
IMHO though, I think that for the sake of clarity and other potential people reading your code it's best to always pass on explicitly all the variables that your subview will require.. code becomes easier to read/debug.
Note: a side effect of the caching is that if you have 2 subviews, variables passed to the first one will get cached and get automatically passed on to the second view as well.. that can lead to debugging trouble sometimes.