fa-surface

This directive is used to create general Famo.us surfaces, which are the leaf nodes of the scene graph. The content inside surfaces is what gets rendered to the screen. This is where you can create form elements, attach images, or output raw text content with one-way databinding . You can include entire complex HTML snippets inside a faSurface, including ngIncludes or custom (vanilla Angular) directives.

Usage

<fa-surface>
  Here's some data-bound content myScopeVariable
</fa-surface>

Example

An fa-surface can use an ng-include to compile an external HTML fragment:

  Edit in Plunker
<fa-app>
  <fa-modifier fa-size="[960, undefined]">
     <fa-surface fa-size="[undefined, undefined]">
       <div ng-include src=" 'helloWorld.html' "></div>
     </fa-surface>
   </fa-modifier>
</fa-app>
<p>This is compiled from an external HTML fragment in helloWorld.html!</p>
angular.module('faSurfaceExampleApp', ['famous.angular']);
fa-app {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

Common Confusions

A Surface is a leaf node

An fa-surface is a leaf node; this means that there should not be Famous-Angular elements nested within an fa-surface.

This following example will NOT work correctly:

 <fa-surface>
    <!-- the contents of a Surface must be standard HTML. -->
    <!-- If a Famo.us component is on a surface, it will not get rendered correctly. -->
    <fa-modifier>
      <fa-surface>This will not work correctly.</fa-surface>
    </fa-modifier>
 </fa-surface>

It will throw this error: "Error: Surfaces are leaf nodes of the Famo.us render tree and cannot accept rendernode children. To include additional Famo.us content inside of a fa-surface, that content must be enclosed in an additional fa-app."

The purpose of an fa-surface is to contain viewable HTML content:

 <fa-surface>
    <!-- content -->
    <!-- databound content with curly braces -->
    <!-- no other Famous renderable nodes allowed inside a Surface-->
 </fa-surface>

Properties on surfaces vs modifiers

With Famous, properties related to layout and visibility belong on a Modifier. A Surface should be added below a Modifier on the Render Tree, as Modifiers affect everything below them.

  Edit in Plunker
<fa-app>
  <fa-surface fa-origin="[.5, 0]">This will not change the origin.</fa-surface>
</fa-app>
angular.module('faSurfaceExampleApp', ['famous.angular']);
fa-app {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

While you can specify fa-size on surfaces themselves, it is not recommended. This is not best practice:

<fa-surface fa-size="[100, 100]"></fa-surface>

Whereas this is the preferred approach:

<fa-modifier fa-size="[100, 100]">
  <fa-surface fa-size="[undefined, undefined]">
  </fa-surface>
</fa-modifier>

You may also omit fa-size="[undefined, undefined]" on the surface and the surface will fill to the size of the modifier, in this case, [100, 100].

In Famous' Render Tree, Modifiers modify all the nodes (other Modifiers and Surfaces) below them. By setting the fa-surface's fa-size to [undefined, undefined], it will inherit from the fa-modifier's fa-size of [100, 100].

Fa-surfaces also cannot have an fa-size, assigned to a function, as is in the case of modifiers, which can take number/array or a function. For example, this will not work:

<fa-surface fa-size="sizeForBoxFunction"></fa-surface>
$scope.sizeForBoxFunction = function() {
   return [75, 75];
};

To reiterate, the best practice to animate or set any layout/visibilty properties of a surface is to do so on a modifier that affects the Surface. The purpose of a Surface is to contain HTML content, whether rendered from a template, or data-bound.

  Edit in Plunker
<fa-app ng-controller="SurfaceCtrl">
  <fa-modifier fa-size="sizeForBoxFunction">
    <fa-surface fa-background-color="'red'"></fa-surface>
  </fa-modifier>
</fa-app>

<script>
  angular.module('faSurfaceExampleApp', ['famous.angular'])
    .controller('SurfaceCtrl', ['$scope', '$famous', function($scope, $famous) {
        
        $scope.sizeForBoxFunction = function() {
           return [75, 75];
        };

    }]);
</script>
fa-app {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

fa-color & fa-background-color

The exceptions of not setting layout/visibility properties on an fa-surface are fa-color and fa-background-color: these two properties are passed through the .setProperties() method available on Famous Surfaces. Take note that they accept a string in the html view. If you do not enclose them in quotation marks, Angular will evaluate it as an object on the scope, but surrounding it with quotation marks will specify it as a string expression.

  Edit in Plunker
<fa-app>
  <fa-modifier fa-size="[200, 50]">
    <fa-surface fa-background-color="'orange'" fa-color="'#fff'">
        This text should be white on an orange background.
    </fa-surface>
  </fa-modifier>
</fa-app>
angular.module('faSurfaceExampleApp', ['famous.angular']);
fa-app {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

ng-class

Ng-Class works on fa-surfaces:

  Edit in Plunker
<fa-app ng-controller="SurfaceCtrl">
  <fa-modifier fa-size="[300, 50]">
    <fa-surface ng-class="{strike: applyStrike}">
      Check box to apply strikethrough!
      <input type="checkbox" ng-model="applyStrike"></input>
    </fa-surface>
  </fa-modifier>
</fa-app>
fa-app {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
.strike {
  text-decoration: line-through;
}
angular.module('faSurfaceExampleApp', ['famous.angular'])
  .controller('SurfaceCtrl', ['$scope', '$famous', function($scope, $famous) {
}]);