Sistema de muro como el de Facebook en Angular JS con múltiples bindings

En este artículo quiero anunciaros una nueva serie avanzada de Javascript en programacion.net. Básicamente, me encantan los sistemas de muros, ya que podemos cubrir varias operaciones o funciones en una sola página web. En programacion.net ya hemos tratado este tema con anterioridad con diversos tutoriales. Este artículo tratará sobre el concepto de sistema de muro con Angular JS 1.4. Futuros artículos tratarán sobre el mismo concepto en el que introduciré tecnologías como ReactJS y AngularJS 2. Si así lo deseas, puedes chequear la demo en este enlace, o si quieres bajártelo, en este otro. Espero que todos disfrutéis de esta nueva serie

Crear página HTML

index.php

Debes incluir la librería de Angular en el tag HEAD

<!DOCTYPE html>
<html>
<head>
<title>Wall System</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="js/wall.js"></script>
<link rel="stylesheet" type="text/css" href="css/wall.css" />
</head>
<body>
<div id="container">
// Wall Grid Code
</div>
</body>
</html>

Wall.js

Crea un archivo Javascript con tu editor de texto favorito. Incluye el modelo de Angular myApp y el controlador myWall.

var app=angular.module("myApp",[]);
app.controller('myWall',  function($scope, $http, $timeout)
{
// All the code comes here.
};

Implementación de Angular

Aplica código de Angular al HTML utilizando ng-app y ng-controller. Este sistema de muro está dividido en múltiples bloques HTML.

<div id="container" ng-app="myApp" ng-controller="myWall">
<div id="wallFeed">
<h1>Wall System</h1>
1) Wall Update Form
2) Wall Feed Grid
[
2.1) Wall Feed Update
2.2) Wall Feed Comment Link
2.3) Wall Feed Comments Grid
2.4) Wall Feed Comment Form
 ]
</div>
</div>

1) Formulario de actualización de muro

Código HTML para mostrar el formulario del campo de texto que actualiza el estado del usuario

<form>
<textarea id="updateBox" ></textarea>
<input type="submit" value="Post" id="wallPost"  />
</form>

2) Grid del feed del muro

Grid con las últimas actualizaciones del muro. Esta parte contiene múltiples operaciones.

<div class="feedBody">
2.1) Wall Feed Update
2.2) Wall Feed Comment Link
2.3) Wall Feed Comments Grid
2.4) Wall Feed Comment Form
</div>

2.1) Actualización del feed del muro

Actualización del estado del usuario

<img src="profile.jpg" class="feedImg" />
<div class="feedText" >
<b>Demo User Name</b>
<a href="#delete1"  class="feedDelete">X</a>
<span>Update Content</span>
</div>

2.2) Enlace de comentarios del feed del muro

Enlace de comentarios para acceder al formulario para comentar.

<div class="feedLinks"><a href="#1" class="commentLink">Comment</a></div>

2.3) Grid de comentarios del muro

Grid de comentarios

<div class="feedCommentGrid">
<img src="commentUser.jpg" class="commentImg" />
<div class="commentText">
<b>Comment User Name</b>
<a href="#11" class="commetDelete">X</a>
<div> Comment Content</div>
</div>
</div>

2.4) Caja de comentar del feed del muro

Formulario de comentarios

<div class="feedCommentForm" >
<textarea class="commentInput"  id="commenInput1"></textarea>
<input type="submit" value="Comment"  class="commentSubmit"/>
</div>

Trabajando con controladores de Angular

Mostrar actualizaciones en el feed

Utilizando el servicio $http de Angular, obtendremos las últimas actualizaciones del usuario basándonos en su ID.

app.controller('myWall',  function($scope, $http, $timeout){

//Default http header
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';

// Newsfeed call
$http({
method : "POST",
url : "newsFeed.php",
data : ""
}).then(function(response)
{
$scope.updatesData=response.data.updates;
});

// Other code
........
........

}

HTML Data Binding

Usando la directiva np-repeat vinculamos el JSON con la plantilla HTML.

<div class="feedBody" ng-repeat="data in updatesData">
2.1) Wall Feed Update
2.2) Wall Feed Comment Link
2.3) Wall Feed Comments Grid
2.4) Wall Feed Comment Form
</div>

newsfeed.php

Aquí tienes como implementar la conexión con la BD y obtener la información del usuario en formato JSON.

{"updates": [
{
"user_id": "1",
"name": "Srinivas Tamada",
"profile_pic": "user1_14572474701.png",
"update_id": "62",
"user_update": "The Wall Script http://www.thewallscript.com",
"comments": [
//Comments Data
]
},
{
"user_id": "3",
"name": "Arun Kumar",
"profile_pic": "user10_14547044391.jpg",
"update_id": "50",
"user_update": "Create Dynamic Subdomains using PHP and Htaccess http://www.9lessons.info/2016/03/how-to-create-dynamic-subdomains-using-php-and-htaccess.html",
"comments": [
//Comments Data
]
}
]}

2.1) Actualización del feed del muro #Angular

Implementación de expresiones de Angular basándonos en ciertos objetos JSON

<img ng-src="{{data.profile_pic}}" class="feedImg" />
<div class="feedText" >
<b>{{data.name}}</b>
<a href="#delete{{data.update_id}}"  class="feedDelete">X</a>
<span>{{data.user_update}}</span>
</div>

Borrar feed

La función de Javascript llama a deleteUpdate.php. Si la respuesta del servidor es true, utilizaremos la función splice que eliminará el objeto del updatesData.

$scope.deleteFeed=function(updateID, index)
{ 
if(updateID>0)
{
$http({
method : "POST",
 url : "deleteUpdate.php",
 data : 'updateID='+updateID
 }).then(function(response){
 if(response){
 $scope.updatesData.splice(index,1);
 }
 }); 
}
}

Código HTML

Usando ng-click llamaremos a la función controlador. Aquí $index hace referencia al objeto data set.

<a href="#delete{{data.update_id}}"  class="feedDelete"

ng-click="deleteFeed(data.update_id, $index)">X</a>

Formulario de comentarios

Haciendo click en el enlace de comentarios, hacemos toggle del formulario. Cambiamos el valor de commentForm basándonos en los clics

<div class="feedLinks"><a href="#1" class="commentLink" ng-click="commentToggle($index)">Comment</a></div>

<div class="feedCommentGrid">
// 2.3.1 Comment Code
</div>

<div class="feedCommentForm" ng-show="commentForm[$index]">
<textarea class="commentInput" ></textarea>
<input type="submit" value="Comment"  class="commentSubmit"/>
</div>

Función Toggle de comentarios

Cambia el valor de commentForm.

$scope.commentForm = {};
$scope.commentToggle=function(index)
{
$scope.commentForm[index] = !$scope.commentForm[index];
// Comment Input focus
$timeout(function () {
document.getElementById('commenInput'+index).focus();
}, 200);
}

JSON de comentarios

newsfeed.php generará el siguiente JSON

{"updates": [
{
"user_id": "1",
"name": "Srinivas Tamada",
"profile_pic": "user1_14572474701.png",
"update_id": "62",
"user_update": "The Wall Script http://www.thewallscript.com",
"comments": [{
          "com_id": "62",
          "uid_fk": "80",
          "comment": "ola",
          "name": "eliasfarias",
          "profile_pic": "user80_14688066161.jpg"
        },
        {
          "com_id": "72",
          "uid_fk": "221",
          "comment": "its a party",
          "name": "rpg",
          "profile_pic": "user221_14690532461.jpg"
        }]
}
]
}

Binding Data de comentarios

<div  class="feedCommentGrid" ng-repeat="commentData in data.comments">
<img ng-src="{{commentData.profile_pic}}" class="commentImg" />
<div class="commentText">
<b>{{commentData.name}}</b>
<a href="#{{data.update_id}}{{$index}}"  class="commetDelete">X</a>
<div>{{commentData.comment}} </div>
</div>
</div>

Borrar comentarios

Función de eliminar comentarios, esto enviará los valores updateID y commentID a deleteComment.php.

// Delete comment
$scope.deleteComment=function(commentIndex, parentIndex, updateID, commentID)
{
if(updateID>0)
{
$http({
method : "POST",
url : "deleteComment.php",
data : 'updateID='+updateID+'&commentID='+commentID
}).then(function(response){
if(response){
$scope.updatesData[parentIndex].comments.splice(commentIndex,1);
}
});
}
}

HTML de borrar comentarios

Usando el ng-click del botón dispararemos la función deleteComment.

<a href="#{{data.update_id}}{{$index}}"  class="commetDelete" 
ng-click="deleteComment($index, $parent.$index, data.update_id, commentData.com_id)">X</a>

Modificar comentario

Submit de comentario utilizando la función de Javascript push.

// Update comment
$scope.updateComment=function(commentSubmitData,index,updateID)
{
if(commentSubmitData.commentValue)
{
$http({
method : "POST",
url : "updateComment.php",
data : 'updateID='+updateID+'&user_comment='+commentSubmitData.commentValue
}).then(function(response){
$scope.updatesData[index].comments.push(response.data.comments[0]);
commentSubmitData.commentValue='';
document.getElementById('commenInput'+index).focus();
}); 
}
}

HTML de modificar comentario

<div class="feedCommentForm" ng-show="commentForm[$index]">
<textarea class="commentInput"  id="commenInput{{$index}}" 
ng-model="commentSubmitData.commentValue" ></textarea>
<input type="submit" value="Comment"  class="commentSubmit" 
ng-click="updateComment(commentSubmitData, $index, data.update_id)"/>
</div>

Modificar formulario del muro

Aquí updateBox es el ID del textarea y feedvalue es el valor del ng-model del textarea. La respuesta JSOn se antepone al uso de la función unshift.

//Focus update box on page load.
document.getElementById('updateBox').focus();

//Update feed.
$scope.updateFeed=function()
{
if($scope.feedValue)
{
$http({
method : "POST",
url : "updateFeed.php",
data : 'user_update='+$scope.feedValue
}).then(function(response)
{
$scope.updatesData.unshift(response.data.updates[0]);
$scope.feedValue="";
document.getElementById('updateBox').focus();
}); 
}
}

Formulario de modificación del muro

Utilizando la directiva ng-click de Angular, al hacer submit dispararemos la función updateFeed().

<form>
<textarea ng-model="feedValue" id="updateBox" ></textarea>
<input type="submit" value="Post" id="wallPost" ng-click="updateFeed()" />
</form>

Filtro para convertir textos en enlaces

Usando expresiones regulares seremos capaces de convertir texto en enlaces.

var app=angular.module("myApp",[]);

// Text to link filter
app.filter('textToLink', function ($sce)
{
var urlReg = /(http|ftp|https)://[w-]+(.[w-]+)+([w.,@?^=%&amp;:/~+#-]*[w@?^=%&amp;/~+#-])?/gi;
return function (text)
{
var htmlData= text.replace(urlReg, '<a target="_blank" href="$&">$&</a>');
return $sce.trustAsHtml(htmlData);
};
});

app.controller('myWall',  function($scope, $http, $timeout)
{
// Wall control code.
};

Aplicando el filtro a los data objects

Simplemente reemplaza el código HTML de la siguiente manera.

<span>{{data.user_update}}</span>
to
<span ng-bind-html="data.user_update | textToLink"></span>


<div>{{commentData.comment}}</div>
to
<div ng-bind-html="commentData.comment | textToLink"></div>

Fuente: 9lessons.info

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP